Dynamische Übergabe von Spaltennamen an UNPIVOT

10

Ich habe eine Tabelle mit folgenden Daten

First         Second        Third         Fourth        Fifth         Sixth
2013-08-20    2013-08-21    2013-08-22    2013-08-23    2013-08-24    2013-08-25

Und mit UNPIVOT

SELECT Data
    ,DATENAME(DW, Data) AS DayName
FROM Cal
UNPIVOT(Data FOR D IN (
            First,
            Second,
            Third,
            Fourth,
            Fifth,
            Sixth  )) AS unpvt

Ich erhalte das folgende Ergebnis

Data        DayName
2013-08-20  Tuesday
2013-08-21  Wednesday
2013-08-22  Thursday
2013-08-23  Friday
2013-08-24  Saturday
2013-08-25  Sunday

Meine Frage ist nun UNPIVOT, ob wir Spaltennamen dynamisch an die übergeben können, damit wir die Anweisung möglicherweise nicht ändern müssen, wenn die Spalten in der Tabelle zunehmen.

Sai Chaitanya M.
quelle

Antworten:

14

Wenn Sie eine unbekannte Anzahl von Spalten haben, die Sie aus dem Pivot entfernen müssen, müssen Sie sich mit der Implementierung von dynamischem SQL befassen.

Sie können verwenden sys.columns, um die Namen aller Spalten in Ihrer calTabelle abzurufen. Wenn Sie die folgende Abfrage verwenden, erhalten Sie eine Liste aller Spalten in Ihrer Tabelle:

select C.name
from sys.columns c
where c.object_id = OBJECT_ID('dbo.cal') 

Jetzt können Sie diese Abfrage zusammen mit verwenden FOR XML PATH, um eine durch Kommas getrennte Liste der Namen zu erstellen, die mit einer auszuführenden Zeichenfolge verknüpft werden sollen:

select @colsUnpivot 
  = stuff((select ','+quotename(C.name)
           FROM sys.columns c
           WHERE c.object_id = OBJECT_ID('dbo.cal') 
           for xml path('')), 1, 1, '')

Schließlich nehmen Sie diese Liste und fügen sie in die auszuführende Abfragezeichenfolge ein, damit die vollständige Abfrage wie folgt aussieht:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
   @query  AS NVARCHAR(MAX)

select @colsUnpivot 
  = stuff((select ','+quotename(C.name)
           FROM sys.columns c
           WHERE c.object_id = OBJECT_ID('dbo.cal') 
           for xml path('')), 1, 1, '')

set @query 
  = 'select data, datename(dw, data) dayname
     from cal
     unpivot
     (
        data
        for d in ('+ @colsunpivot +')
     ) u'

exec sp_executesql @query;

Siehe SQL Fiddle mit Demo

Taryn
quelle