select all attributes of columns, constraints, tables of a database
-
01-07-2021 - |
Question
I am fetching all attributes of tables,columns,constraints from information_schema in MySql
select t.*,c.*,k.*
from information_schema.tables t
inner join information_schema.COLUMNS c on c.table_name=t.table_name
left outer join information_schema.key_column_usage k on
c.column_name=k.column_name
and k.table_name=t.table_name and k.referenced_column_name is not NULL
where t.table_schema='test' order by t.table_name;
Problem with this query is that if I have a table in any other database with same name i also get the columns of that table even i have a clear where condition for this particular database
If I do not use left outer join I find many columns missing because all columns are not the foreign key
I need to improve this query along-with a bit guidance, however a quite different solution is also acceptable.
Number of rows of result of improved query must be equal to
select count(*) from information_schema.columns c where c.table_schema='test';
Thanks for any help in advance :)
Solution
Your where
clause ensures that you're only looking at tables in schema test
, but nothing in your join
/on
clauses ensures that your columns come from the same schema as the tables. (on c.table_name=t.table_name
merely ensures that the column described by c
comes from a table with the same name as that described by t
.) And, similarly for key_column_usage
. So, you can write:
select t.*,c.*,k.*
from information_schema.tables t
inner join information_schema.COLUMNS c
on c.table_schema=t.table_schema
and c.table_name=t.table_name
left outer join information_schema.key_column_usage k
on k.table_schema=t.table_schema
and k.table_name=t.table_name
and k.column_name=c.column_name
and k.referenced_column_name is not NULL
where t.table_schema='test'
order by t.table_name;
That said, this could still return more rows than your count(*)
reports, because a single column can, in principle, belong to multiple foreign keys. To ensure that you only get one row per column, meaning only one foreign-key for a column, you can add a GROUP BY
clause:
where t.table_schema='test'
group by t.table_schema, t.table_name, c.column_name
order by t.table_name;
(where I've taken advantage of MySQL's support for "hidden" GROUP BY columns).