Есть ли способ создать запрос UNION ALL, когда столбцы находятся в другом порядке - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть 600 таблиц для выполнения запроса UNION ALL. К сожалению, порядок столбцов в каждой таблице различен, однако они всегда будут иметь одинаковые имена - пример:

Таблица 1

    Item, Cost, ID, Code, Location

Таблица 2

    Cost, Id, Code, Location, Item

Таблица 3

    Id, Code, Cost, Item, Location

Есть ли способ написать запрос объединения, чтобы он соответствовал именам столбцов, независимо от порядка в исходной таблице?

Ответы [ 2 ]

2 голосов
/ 15 апреля 2020

Следующий код найдет все таблицы с указанными столбцами в любом порядке. Затем он будет использовать список для составления запроса, объединяющего данные из всех таблиц со столбцами в одинаковом порядке для каждой таблицы.

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 );

В зависимости от ваших потребностей вы можете выполнить его один раз, чтобы получить запрос и cut'n'paste результирующий оператор в какое-то подходящее место, например, хранимую процедуру или представление, или вы можете позволить ему генерировать динамику c SQL и выполнять его.

Дополнительная проверка, например, исключая системные таблицы, оставлено читателю.

2 голосов
/ 15 апреля 2020

Увы, нет. UNION ALL идет по позиции, а не по именам. Однако вы можете сгенерировать столбцы:

select string_agg(column_name, ', ')
from information_schema.columns
where table_name = ? and
      table_schema = ?;

Затем вы можете подключить список к своему коду.

...