使用 SQL 服务器联合 50 多个具有不同列数的表

Union 50+ tables with different number of columns using SQL Server

我有 50 多个不同的 table,我想将它们合并成一个大的 table。所有 table 都有不同的列数。

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

例如:

(
select col1
        , null as col2 
        , col3
 from   table1

union all

 select col1
       , col2
       , null as col
from   table2
)

虽然这可行,但非常耗时。有没有更好、更有效的方法将这些 table 合并为一个?与超过 50 table 一样,我将有数千行代码。

谢谢!

您可以查询 SQL 服务器元数据,并根据结果动态构建 SQL 语句。这可以用任何编程语言完成,包括 T-SQL 本身。

这是一个粗略的例子;执行此查询,copy/paste 将结果返回查询 window,然后执行该查询。

如果 50 个 table 具有相似的名称(例如,都以 Foo 开头),那么您可以替换详尽的 table 列表(在我的示例中为 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?