0

我有以下 SQL 代码,它返回数据库中的表以及每个表中的主键字段。

SELECT Keys.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS Constraints
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME
AND Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
WHERE Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'

事实上,它只显示那些具有主键的表。如何修改sql以显示所有表,而那些没有主键的表将在“主键”列中显示“null”?

4

2 回答 2

1

为此,您需要从所有表的列表开始,然后使用左外连接连接这些表:

SELECT t.TABLE_NAME As 'Table Name',
       Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES t left outer join
     INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
     on t.TABLE_NAME = Constraints.Table_name and
        t.Table_Schema = Constraints.Table_Schema left outer join
     INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys 
     ON Constraints.TABLE_NAME = Keys.TABLE_NAME and
        Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME and
        Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
于 2012-09-10T17:44:47.983 回答
1

默认情况下,“连接”是内连接,根据连接条件,如果另一个表中有对应的行,它只会显示一行。所以,你不会想在这里使用直接连接,你需要一个左连接、右连接或完全连接,它允许一个表返回没有匹配的行。

但是在这里您不能只切换到左连接,因为 table_constraints 仅列出具有约束的那些,并且您的 where 约束将过滤掉没有主键的行。

因此,您可以引入 information_schema.tables 以包含每个表,然后将主键条件移动到连接条件而不是 where 子句。它可能看起来像:

SELECT t.TABLE_NAME As 'Table Name',  
Keys.COLUMN_NAME AS 'Primary Key'  
FROM 
INFORMATION_SCHEMA.TABLES as t
left join 
INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS Constraints  
on t.TABLE_NAME = constraints.TABLE_NAME and t.TABLE_SCHEMA = constraints.TABLE_SCHEMA
left JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys  
ON Constraints.TABLE_NAME = Keys.TABLE_NAME  
AND Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME  
and Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY' 
于 2012-09-10T17:46:59.793 回答