当列的顺序不同时创建 UNION ALL 查询
Create a UNION ALL query when the columns are in different order
我有 600 tables 来执行 UNION ALL
查询。不幸的是,每个 table 中的列顺序各不相同,但它们将始终具有相同的名称 - 例如:
Table 1
Item, Cost, ID, Code, Location
Table 2
Cost, Id, Code, Location, Item
Table 3
Id, Code, Cost, Item, Location
有没有办法编写 Union 查询,使其与列名匹配,而不管原始顺序如何 table?
唉,没有。 UNION ALL
按位置而不是按名称。但是,您可以生成列:
select string_agg(column_name, ', ')
from information_schema.columns
where table_name = ? and
table_schema = ?;
然后您可以将该列表插入您的代码。
以下代码将以任意顺序查找具有指定列的所有 table。然后它将使用该列表 assemble 一个查询,该查询将所有 table 的数据与每个 table.
的列以相同的顺序合并
declare @Query as NVarChar(max);
-- Quote column names here as needed:
declare @Prefix as NVarChar(64) = N'select Id, Item, Code, Location, Cost from ';
declare @Suffix as NVarChar(64) = NChar( 13 ) + NChar( 10 ) + N'union all' + NChar( 13 ) + NChar( 10 );
with
TargetTables as (
-- All of the table which have the specified list of columns, regardless of column order.
select T.Table_Schema, T.Table_Name
from Information_Schema.Tables as T inner join
Information_Schema.Columns as C on C.Table_Schema = T.Table_Schema and C.Table_Name = T.Table_Name
where C.Column_Name in ( 'Id', 'Item', 'Code', 'Location', 'Cost' ) -- Do not quote column names here.
group by T.Table_Schema, T.Table_Name
having Count( Distinct C.Column_Name ) = 5
)
-- Build the query by inserting @Prefix and @Suffix around each properly quoted table schema and name.
select @Query = (
select @Prefix + QuoteName( Table_Schema ) + '.' + QuoteName( Table_Name ) + @Suffix
from TargetTables
order by Table_Schema, Table_Name
for XML path(''), type).value('.[1]', 'VarChar(max)' );
-- Clean up the tail end of the query.
select @Query = Stuff( @Query, DataLength( @Query ) / DataLength( N'-' ) - DataLength( @Suffix ) / DataLength( N'-' ) + 1, DataLength( @Suffix ) / DataLength( N'-' ), N';' );
-- Display the resulting query.
-- In SSMS use Results To Text (Ctrl-T) to see the query on multiple lines.
select @Query as Query;
-- Execute the query. NB: The parentheses are required.
execute ( @Query );
根据您的需要,您可以 运行 这一次获取查询并将生成的语句剪切并粘贴到某个适当的位置,例如存储过程或视图,或者您可以让它生成动态 SQL 并执行它。
额外的验证,例如排除系统tables,留给reader.
我有 600 tables 来执行 UNION ALL
查询。不幸的是,每个 table 中的列顺序各不相同,但它们将始终具有相同的名称 - 例如:
Table 1
Item, Cost, ID, Code, Location
Table 2
Cost, Id, Code, Location, Item
Table 3
Id, Code, Cost, Item, Location
有没有办法编写 Union 查询,使其与列名匹配,而不管原始顺序如何 table?
唉,没有。 UNION ALL
按位置而不是按名称。但是,您可以生成列:
select string_agg(column_name, ', ')
from information_schema.columns
where table_name = ? and
table_schema = ?;
然后您可以将该列表插入您的代码。
以下代码将以任意顺序查找具有指定列的所有 table。然后它将使用该列表 assemble 一个查询,该查询将所有 table 的数据与每个 table.
的列以相同的顺序合并declare @Query as NVarChar(max);
-- Quote column names here as needed:
declare @Prefix as NVarChar(64) = N'select Id, Item, Code, Location, Cost from ';
declare @Suffix as NVarChar(64) = NChar( 13 ) + NChar( 10 ) + N'union all' + NChar( 13 ) + NChar( 10 );
with
TargetTables as (
-- All of the table which have the specified list of columns, regardless of column order.
select T.Table_Schema, T.Table_Name
from Information_Schema.Tables as T inner join
Information_Schema.Columns as C on C.Table_Schema = T.Table_Schema and C.Table_Name = T.Table_Name
where C.Column_Name in ( 'Id', 'Item', 'Code', 'Location', 'Cost' ) -- Do not quote column names here.
group by T.Table_Schema, T.Table_Name
having Count( Distinct C.Column_Name ) = 5
)
-- Build the query by inserting @Prefix and @Suffix around each properly quoted table schema and name.
select @Query = (
select @Prefix + QuoteName( Table_Schema ) + '.' + QuoteName( Table_Name ) + @Suffix
from TargetTables
order by Table_Schema, Table_Name
for XML path(''), type).value('.[1]', 'VarChar(max)' );
-- Clean up the tail end of the query.
select @Query = Stuff( @Query, DataLength( @Query ) / DataLength( N'-' ) - DataLength( @Suffix ) / DataLength( N'-' ) + 1, DataLength( @Suffix ) / DataLength( N'-' ), N';' );
-- Display the resulting query.
-- In SSMS use Results To Text (Ctrl-T) to see the query on multiple lines.
select @Query as Query;
-- Execute the query. NB: The parentheses are required.
execute ( @Query );
根据您的需要,您可以 运行 这一次获取查询并将生成的语句剪切并粘贴到某个适当的位置,例如存储过程或视图,或者您可以让它生成动态 SQL 并执行它。
额外的验证,例如排除系统tables,留给reader.