【问题标题】:Query to find possible columns that should be foreign keys?查询以查找应该是外键的可能列?
【发布时间】:2012-07-25 23:49:13
【问题描述】:

我正在寻找一个查询来帮助清理一个旧数据库,该数据库在应有的关系中没有很多关系。我不需要它是完美的,只是为了帮助指导我开始清理并开始执行数据完整性。

我假设所有表都具有正确的主键,并且尚未相关的表中的列具有相同的名称。

从理论上讲,我可以拥有三个表,其中一个具有复合键(我不会选择这样设计数据库,但在清理它时受到限制,并且这些类型的复合/主/外键很常见):

Case.CaseId (PK)
Workstep.WorkstepId (PK)
Workstep.CaseId (PK,FK)
WorkQueue.CaseId(与 Ca​​se.CaseId 无关,但应该是)

我希望能够做的是运行查询并得出结果,这些结果会给我一些不相关但应该相关的表名、列名和表的外键,例如:

表名,列名,应该与主键相关
工作队列、CaseId、Case.CaseId

请参阅下面我使用的 SQL,但它返回任何主键,即使是主键但也是外键一部分的主键。再次使用我的示例和下面的 SQL,而不是返回 1 行,我得到 2:

表名,列名,应该与主键相关
WorkQueue、CaseId、Workstep.CaseId(我不想要这一行,因为它也与“真实”主键 Case.CaseId 有关)
工作队列、CaseId、Case.CaseId

    SELECT 
    SubqueryAllPotentialForeignKeys.TABLE_NAME
    ,SubqueryAllPotentialForeignKeys.COLUMN_NAME
    ,(PrimaryKeys.TABLE_NAME + '.' + PrimaryKeys.COLUMN_NAME) as 'Possible Primary Key'

--all potential foreign keys (column name matches another column name but there is no reference from this column anywhere else)
FROM
    (   
    SELECT
        INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
        ,INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME
    FROM
        INFORMATION_SCHEMA.COLUMNS
    WHERE
        --only get columns that are in multiple tables
        INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME IN 
        (
            SELECT COLUMN_NAME FROM
                (SELECT COLUMN_NAME, COUNT(COLUMN_NAME) AS ColNameCount FROM INFORMATION_SCHEMA.COLUMNS GROUP BY COLUMN_NAME) AS SubQueryColumns
            WHERE ColNameCount > 1
        )

        --only get the table.column if not part of a foreign or primary key
        EXCEPT
        (
            SELECT TABLE_NAME, COLUMN_NAME  FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE 
        )

    ) AS SubqueryAllPotentialForeignKeys

LEFT JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS PrimaryKeys ON 
    SubqueryAllPotentialForeignKeys.COLUMN_NAME = PrimaryKeys.COLUMN_NAME

--when finding possible keys for our columns that don't have references, limit to primary keys
WHERE 
    PrimaryKeys.CONSTRAINT_NAME LIKE '%PK_%'

ORDER BY TABLE_NAME, COLUMN_NAME

【问题讨论】:

    标签: sql-server tsql foreign-keys relational-database primary-key


    【解决方案1】:

    这可能不是世界上最美丽的东西,但效果非常好:

        SELECT * FROM
    (
        SELECT 
            SubqueryAllPotentialForeignKeys.TABLE_NAME
            ,SubqueryAllPotentialForeignKeys.COLUMN_NAME
            ,(PrimaryKeys.TABLE_NAME + '.' + PrimaryKeys.COLUMN_NAME) as 'Possible Primary Key'
    
        --all potential foreign keys (column name matches another column name but there is no reference from this column anywhere else)
        FROM
            (   
            SELECT
                INFORMATION_SCHEMA.COLUMNS.TABLE_NAME
                ,INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME
            FROM
                INFORMATION_SCHEMA.COLUMNS
            WHERE
                --only get columns that are in multiple tables
                INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME IN 
                (
                    SELECT COLUMN_NAME FROM
                        (SELECT COLUMN_NAME, COUNT(COLUMN_NAME) AS ColNameCount FROM INFORMATION_SCHEMA.COLUMNS GROUP BY COLUMN_NAME) AS SubQueryColumns
                    WHERE ColNameCount > 1
                )
    
                --only get the table.column if not part of a foreign or primary key
                EXCEPT
                (
                    SELECT TABLE_NAME, COLUMN_NAME  FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE 
                ) 
    
            ) AS SubqueryAllPotentialForeignKeys
    
        LEFT JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS PrimaryKeys ON 
            SubqueryAllPotentialForeignKeys.COLUMN_NAME = PrimaryKeys.COLUMN_NAME
    
        --when finding possible keys for our columns that don't have references, limit to primary keys
        WHERE 
            PrimaryKeys.CONSTRAINT_NAME LIKE '%PK_%'
    ) AS Subquery
    
    --exclude all keys that are primary but also foreign
    WHERE [Possible Primary Key] NOT IN
        (
            SELECT (TABLE_NAME + '.' + COLUMN_NAME)
            FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
            WHERE CONSTRAINT_NAME LIKE 'FK_%'
        ) 
    
    ORDER BY TABLE_NAME, COLUMN_NAME
    

    【讨论】:

      猜你喜欢
      • 2011-12-07
      • 2023-01-20
      • 2012-05-15
      • 2020-11-15
      • 1970-01-01
      • 2019-04-29
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多