Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Requête SQL Server :les lignes font des colonnes (Pivot ?)

Le pivotement ressemble beaucoup au regroupement. Vous pouvez le voir comme un groupement limité avec un "effet spécial". La limitation consiste dans le fait qu'il ne peut y avoir qu'une seule colonne agrégée. (Dans une requête GROUP BY normale, vous pouvez en avoir plusieurs, naturellement.) Et par "effet spécial", je veux dire, bien sûr, que l'une des autres colonnes (et, encore une fois, une seule) est transformée en plusieurs colonnes.

Prenons votre requête GROUP BY comme exemple. Vous avez trois colonnes dans la sortie. L'un d'eux, Count , est la colonne même qui contient des informations agrégées. C'est celui qui serait dispersé sur plusieurs colonnes dans une requête PIVOT. Une autre colonne, Priority , est l'une des deux autres colonnes par lesquelles les résultats sont regroupés et également celle qui doit être pivotée. Enfin, EntryDate est l'autre colonne GROUP BY. Il doit simplement rester tel quel, car il ne participe pas directement au pivotement.

Voyons maintenant comment votre SELECT principal est transformé d'une requête GROUP BY habituelle en une requête PIVOT, étape par étape :

  1. Étant donné que le regroupement est implicite dans une requête PIVOT, la clause GROUP BY est supprimée. Au lieu de cela, une clause PIVOT est introduite.

  2. Le Count l'expression de la colonne est déplacée de la clause SELECT vers la clause PIVOT.

  3. Le fractionnement de la Priority colonne est définie dans la clause PIVOT.

  4. La Priority et Count les colonnes de la clause SELECT sont remplacées par la liste des colonnes définies dans la clause PIVOT.

  5. La EntryDate la colonne reste inchangée dans la clause SELECT.

Et voici la requête résultante, avec des commentaires marquant chaque partie de la transformation décrite ci-dessus :

WITH TATH(Priority, EntryDate) AS 
(
    SELECT TH.Priority as Priority, DATEADD(dd, 0, DATEDIFF(dd, 0, entryDate)) as EntryDate
      FROM TicketAssignment TA, TicketHeader TH 
     WHERE TA.TicketID = TH.TicketID   
       AND TA.Company = 'IT'
       AND TA.CurrentRole IN ('SA1B','SA1C','SDA')
) 
SELECT
  convert(varchar(10), EntryDate,103) as EntryDate,                       -- #5
  [0] AS Priority0, [1] AS Priority1, [2] AS Priority2, [3] AS Priority3  -- #4
FROM TATH
PIVOT (                                                                   -- #1
  COUNT(*)                                                                -- #2
  FOR Priority IN ([0], [1], [2], [3])                                    -- #3
) p

/*  -- your original main query, for comparison
SELECT
  Priority,                                                               -- #4
  convert(varchar(10),                                                    -- #5
  EntryDate,103) as EntryDate, COUNT(*) AS Count                          -- ##2&4
FROM TATH 
GROUP BY Priority, EntryDate                                              -- #1
*/

Il y a une note supplémentaire sur la liste des colonnes dans la clause PIVOT. Tout d'abord, vous devez comprendre que l'ensemble résultant d'une requête SQL est censé être fixe en termes de nombre de colonnes et de leurs noms. Cela signifie que vous devez énumérer explicitement toutes les colonnes transformées que vous souhaitez voir dans la sortie. Les noms sont dérivés des valeurs de la colonne en cours de pivotement, mais ils doivent être spécifiés en tant que noms , pas en tant que valeurs. C'est pourquoi vous pouvez voir des crochets autour des numéros indiqués. Puisque les nombres eux-mêmes ne satisfont pas les règles pour les identifiants réguliers , ils doivent être délimités.

Vous pouvez également voir que vous pouvez attribuer des alias aux colonnes pivotées dans la clause SELECT comme n'importe quelle autre colonne ou expression. Donc, à la fin, vous n'avez pas à vous retrouver avec le 0 sans signification , 1 etc. et à la place, vous pouvez attribuer à ces colonnes les noms de votre choix.

Si vous souhaitez que le nombre et/ou les noms des colonnes pivotées soient dynamiques, vous devrez créer la requête de manière dynamique, c'est-à-dire collecter d'abord les noms, puis les incorporer dans une chaîne contenant le reste des requête et invoquer la requête finale avec EXEC () ou EXEC sp_executesql . Vous pouvez rechercher sur ce site pour plus d'informations sur le pivotement dynamique.