2016-05-09 26 views
0

Ich habe über 50 verschiedene Tabellen, die ich zu einer großen Tabelle kombinieren möchte. Alle Tabellen haben eine unterschiedliche Anzahl von Spalten.Union 50+ Tabellen mit unterschiedlicher Anzahl von Spalten mit SQL Server

Derzeit, um die Tabellen zusammenzuführen, schreibe ich eine individuelle select-Anweisung für jede der Tabellen und Einfügen einer Null-Spalte, wenn diese Spalte nicht in der Tabelle vorhanden ist. Dann benutze ich UNION ALL, um sie miteinander zu verbinden.

Zum Beispiel:

(
select col1 
     , null as col2 
     , col3 
from table1 

union all 

select col1 
     , col2 
     , null as col 
from table2 
) 

Obwohl dies funktioniert, ist es sehr manuelles und zeitaufwendig. Gibt es eine bessere, effizientere Möglichkeit, diese Tabellen zu einer Einheit zusammenzufassen? Wie bei über 50 Tabellen werde ich Tausende von Codezeilen haben.

Vielen Dank!

+1

Mögliche [XY Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Was versuchst du zu erreichen? Sicherlich werden Sie einige nicht verwandte Tabellenschemas nur zum Spaß zusammenfügen. –

+0

Oh Entschuldigung. Die Tabellen sind alle verwandt und beziehen sich auf die gleichen Daten, aber aufgrund der Art, wie die ursprünglichen Daten extrahiert wurden, sind nicht alle Spalten in allen Tabellen enthalten. Ich versuche, eine große Tabelle zu erstellen, die alle Tabellen an 1 anhängt, damit ich die Daten im Ganzen abfragen kann. Ich kann jedoch nicht nur bestimmte Spalten auswählen, weil in bestimmten Tabellen Spalten fehlen, die ich tatsächlich abfragen muss. – a123z

+0

Ist das eine einmalige Abfrage? Sobald Sie alle Daten in einer Tabelle haben, müssen Sie erneut ausführen? –

Antwort

0

Sie können SQL Server-Metadaten abfragen und daraus dynamisch eine SQL-Anweisung erstellen. Dies kann in jeder Programmiersprache erfolgen, einschließlich T-SQL selbst.

Hier ist ein grobes Beispiel; Führen Sie diese Abfrage aus, kopieren Sie das Ergebnis in das Abfragefenster und fügen Sie es ein.

Wenn die 50 Tabellen ähnliche Namen haben (z. B. alle beginnen mit Foo), dann können Sie die erschöpfende Tabellenliste (WHERE TABLE_NAME IN ('table1', 'table2', 'table3') in meinem Beispiel) durch WHERE TABLE_NAME LIKE 'Foo%' ersetzen.

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, '') 

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

+0

Das ist erstaunlich, danke! – a123z

+0

FYC, ich habe die Abfrage verfeinert und einen letzten Verkettungsschritt hinzugefügt. Jetzt ist das Ergebnis wirklich die fertige Abfrage. –

Verwandte Themen