Динамічно передаючи назви стовпців до UNPIVOT


10

У мене є таблиця з наступними даними

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

І використовуючи UNPIVOT

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

Я отримую такий результат

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

Тепер моє питання полягає в тому, чи можемо ми передати назви стовпців динамічно таким UNPIVOTчином, що коли стовпці в таблиці збільшуються, нам, можливо, не доведеться змінювати оператор.

Відповіді:


14

Якщо у вас буде невідома кількість стовпців, які вам потрібно буде відкрутити, тоді вам доведеться переглянути реалізацію динамічного SQL.

Ви можете використовувати sys.columnsназви всіх стовпців calтаблиці. Якщо ви користуєтесь наступним запитом, ви отримаєте список усіх стовпців таблиці:

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

Тепер ви можете використовувати цей запит разом з FOR XML PATHдля створення списку, розділеного комою, імен, які слід об'єднати в рядок, який потрібно виконати:

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

Нарешті, ви візьмете цей список і помістите його у рядок запиту для виконання, щоб повний запит виглядав так:

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;

Див. SQL Fiddle with Demo

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.