Динамическая передача имен столбцов в 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 с демо

Тарын
источник