Passando dinamicamente i nomi delle colonne a UNPIVOT


10

Ho una tabella con i seguenti dati

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

E usando UNPIVOT

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

Ottengo il seguente risultato

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

Ora la mia domanda è: possiamo passare dinamicamente i nomi UNPIVOTdelle colonne in modo tale che quando le colonne nella tabella aumentano potremmo non dover modificare l'istruzione.

Risposte:


14

Se hai un numero sconosciuto di colonne che dovrai annullare la rotazione, dovrai guardare all'implementazione dell'SQL dinamico.

È possibile utilizzare sys.columnsper ottenere i nomi di tutte le colonne nella caltabella. Se si utilizza la seguente query, verrà visualizzato l'elenco di tutte le colonne nella tabella:

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

Ora puoi usare questa query insieme FOR XML PATHa creare un elenco separato da virgole dei nomi da concatenare a una stringa da eseguire:

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

Infine, prenderai questo elenco e lo inserirai nella stringa di query da eseguire in modo che la query completa sia simile a:

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;

Vedi SQL Fiddle with Demo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.