使用 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?
我有 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?