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;
  1. 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

  2. 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 :)

Was it helpful?

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top