Passage dynamique des noms de colonne à UNPIVOT


10

J'ai un tableau avec les données suivantes

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

Et en utilisant UNPIVOT

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

J'obtiens le résultat suivant

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

Maintenant, ma question est de savoir si nous pouvons transmettre des noms de colonnes de manière dynamique à la UNPIVOTafin que lorsque les colonnes du tableau augmentent, nous n'aurons peut-être pas à modifier l'instruction.

Réponses:


14

Si vous allez avoir un nombre inconnu de colonnes que vous devrez annuler, vous devrez alors envisager d'implémenter le SQL dynamique.

Vous pouvez utiliser sys.columnspour obtenir les noms de toutes les colonnes de votre caltable. Si vous utilisez la requête suivante, vous obtiendrez la liste de toutes les colonnes de votre table:

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

Vous pouvez maintenant utiliser cette requête avec FOR XML PATHpour créer une liste séparée par des virgules des noms à concaténer à une chaîne à exécuter:

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

Enfin, vous prendrez cette liste et la placerez dans votre chaîne de requête à exécuter pour que la requête complète ressemble à:

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;

Voir SQL Fiddle avec démo

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.