使用SQL Server使用不同列数的50+表联合

时间:2016-05-09 08:53:27

标签: sql-server union union-all

我有超过50个不同的表格,我想将它们组合成一个大表格。所有表都有不同的列数。

目前,为了将表合并在一起,我正在为每个表编写一个单独的select语句,如果该列不存在于表中,则插入一个空列。然后我使用UNION ALL将它们组合在一起。

例如:

volumes

虽然这有效,但它非常手动且耗时。是否有更好,更有效的方法将这些表合并为一个?与50多个表一样,我将拥有数千行代码。

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以查询SQL Server元数据,并从结果中动态构造SQL语句。这可以用任何编程语言完成,包括T-SQL本身。

这是一个粗略的例子;执行此查询,将结果复制/粘贴回查询窗口,然后执行该操作。

如果50个表具有相似的名称(例如,所有表都以Foo开头),那么您可以用WHERE TABLE_NAME IN ('table1', 'table2', 'table3')替换详尽的表格列表(在我的示例中为WHERE TABLE_NAME LIKE 'Foo%')。

WITH
    AllTables (TABLE_NAME) AS (
        SELECT TABLE_NAME
        FROM INFORMATION_SCHEMA.TABLES
        WHERE TABLE_NAME IN ('table1', 'table2', 'table3')
    ),
    TablesWithSelectors (TABLE_NAME, COLUMN_NAME, Selector) AS (
        SELECT t.TABLE_NAME, a.COLUMN_NAME, CASE WHEN b.COLUMN_NAME IS NULL THEN 'NULL AS ' ELSE '' END + a.COLUMN_NAME
        FROM AllTables t
        CROSS JOIN (SELECT DISTINCT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME IN (SELECT TABLE_NAME FROM AllTables)) a
        LEFT OUTER JOIN INFORMATION_SCHEMA.COLUMNS b ON b.TABLE_NAME = t.TABLE_NAME AND b.COLUMN_NAME = a.COLUMN_NAME
    ),
    SelectStatements (Sql) AS (
        SELECT
            'SELECT ' +
            STUFF((
                SELECT ', ' + Selector
                FROM TablesWithSelectors
                WHERE TABLE_NAME = r.TABLE_NAME
                FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
            , 1, 2, '') +
            ' FROM ' +
            TABLE_NAME
        FROM TablesWithSelectors r
        GROUP BY TABLE_NAME
    )
SELECT STUFF((
        SELECT ' UNION ALL ' + sql
        FROM SelectStatements
        FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)'), 1, 11, '')

感谢: How to use GROUP BY to concatenate strings in SQL Server?