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

Colonnes dynamiques - SQL Server - Mois en colonnes

Vos données sont déjà pivotées, mais doivent être pivotées à un niveau différent. Je pense que la meilleure façon de gérer cela est de d'abord l'annuler, puis de gérer le niveau de pivot correct en second.

Étape 1 :Annuler le pivot

Vous pouvez utiliser SQL 2005 UNPIVOT ou utilisez une technique CROSS JOIN. Voici des exemples des deux. Notez que j'ai omis des mois au milieu pour garder les choses simples. Ajoutez-les simplement.

-- CROSS JOIN method (also works in SQL 2000)
SELECT
   P.Project,
   Mo =
      DateAdd(mm,
         X.MonthNum,
         DateAdd(yy, P.[Year] - 1900, '19000101')
      ),
   Amount = 
      CASE X.MonthNum
         WHEN 0 THEN Jan
         WHEN 1 THEN Feb
         WHEN 11 THEN Dec
      END
FROM
   ProjectData P
   CROSS JOIN (
      SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 11
   ) X (MonthNum)

Chaque ligne est répétée 12 fois, puis une instruction CASE n'extrait qu'un mois pour chaque ligne, laissant les données parfaitement non pivotées.

-- UNPIVOT method
SELECT
    P.Project,
    Mo =
       DateAdd(mm,
          Convert(int, P.MonthNum),
          DateAdd(yy, P.[Year] - 1900, '19000101')
       ),
    P.Amount
FROM
   (
      SELECT Project, [Year], [0] = Jan, [1] = Feb, [11] = Dec
      FROM ProjectData
   ) X UNPIVOT (Amount FOR MonthNum IN ([0], [1], [11])) P

DROP TABLE ProjectData

Ni l'une ni l'autre de ces méthodes n'est clairement gagnante en performances tout le temps. Parfois, l'un fonctionne mieux que l'autre (selon les données pivotées). La méthode UNPIVOT utilise un filtre dans le plan d'exécution que le CROSS JOIN ne fait pas.

Étape 2 :Pivotez à nouveau

Maintenant, comment utiliser les données non pivotées. Vous n'avez pas dit comment votre quelqu'un consommera cela, mais puisque vous aurez besoin de mettre les données dans un fichier de sortie quelconque, je propose d'utiliser SSRS (Sql Server Reporting Services), qui est fourni avec SQL Server 2005 sans frais supplémentaires.

Utilisez simplement la Matrice objet de rapport pour faire pivoter l'une des requêtes ci-dessus. Cet objet détermine avec plaisir les valeurs de données à transformer en étiquettes de colonne lors de l'exécution du rapport et ressemble exactement à ce dont vous avez besoin. Si vous ajoutez une colonne qui formate la date exactement comme vous le souhaitez, vous pouvez trier par la colonne Mo, mais utilisez la nouvelle expression comme étiquette de colonne.

SSRS propose également une grande variété de formats et d'options de planification. Par exemple, vous pouvez lui envoyer un fichier Excel par e-mail ou enregistrer une page Web dans un partage de fichiers.

Veuillez me faire savoir si j'ai oublié quelque chose.

Pour tous ceux qui souhaitent voir le code ci-dessus en action, voici un script de création pour vous :

USE tempdb

CREATE TABLE ProjectData (
    Project varchar(10),
    [Year] int,
    Jan decimal(15, 2),
    Feb decimal(15, 2),
    Dec decimal(15, 2)
)

SET NOCOUNT ON

INSERT ProjectData VALUES ('11-11079', 2008, 0.0, 0.0, 75244.90)
INSERT ProjectData VALUES ('11-11079', 2009, 466.0, 0.0, 0.0)
INSERT ProjectData VALUES ('11-11079', 2010, 855.0, 0.0, 0.0)
INSERT ProjectData VALUES ('01-11052', 2009, 56131.0, 0.0, 0.0)