Question

J'ai une table avec les colonnes sales (int) , mois (int) . Je veux récupérer la somme des ventes correspondant à chaque mois. J'ai besoin d'une sortie sous forme de 12 colonnes correspondant à chaque mois dans lequel il y aura un seul enregistrement contenant les ventes pour chaque colonne (mois).

Était-ce utile?

La solution

Vous devriez consulter PIVOT pour changer de ligne avec des colonnes. . Cela empêche une instruction select pour chaque mois. Quelque chose comme ça:

DECLARE @salesTable TABLE
(
    [month] INT,
    sales INT
)

-- Note that I use SQL Server 2008 INSERT syntax here for inserting
-- multiple rows in one statement!
INSERT INTO @salesTable
VALUES (0, 2) ,(0, 2) ,(1, 2) ,(1, 2) ,(2, 2)
      ,(3, 2) ,(3, 2) ,(4, 2) ,(4, 2) ,(5, 2)
      ,(6, 2) ,(6, 2) ,(7, 2) ,(8, 2) ,(8, 2)
      ,(9, 2) ,(10, 2) ,(10, 2) ,(11, 2) ,(11, 2)

SELECT [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]
FROM
(
    SELECT [month], sales
    FROM @salesTable
) AS SourceTable
PIVOT
(
    SUM(sales)
    FOR [month] IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11])
) AS PivotTable

Autres conseils

Pas joli ... mais ça marche bien

SELECT
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 1) [Sales1],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 2) [Sales2],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 3) [Sales3],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 4) [Sales4],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 5) [Sales5],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 6) [Sales6],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 7) [Sales7],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 8) [Sales8],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 9) [Sales9],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 10) [Sales10],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 11) [Sales11],
    (SELECT SUM(Sales) FROM SalesTable WHERE [Month] = 12) [Sales12]

Voici une autre façon d’écrire le pivot qui vous donne un peu plus de contrôle (en particulier sur les noms de colonne). Il est également un peu plus facile de générer du SQL dynamique pour.

Cela ressemble à la réponse de Robin, mais présente l'avantage de ne toucher la table qu'une seule fois:

select
  Sales1 = sum( case when Month = 1 then Sales end )
, Sales2 = sum( case when Month = 2 then Sales end )
, Sales3 = sum( case when Month = 3 then Sales end )
-- etc..
from SalesTable;

J'ai fait des recherches et il semble que le nouvel opérateur pivot ne soit qu'un sucre syntaxique pour ce type de requête. Les plans de requête finissent par paraître identiques.

Autre particularité intéressante, l’opérateur univote semble également être simplement du sucre syntaxe. Par exemple:

Si vous avez une table du type:

Create Table Sales ( JanSales int, FebSales int, MarchSales int...)

Vous pouvez écrire:

 select unpivoted.monthName, unpivoted.sales
 from Sales s
 outer apply (
    select 'Jan', JanSales union all
    select 'Feb', FebSales union all
    select 'March', MarchSales
 ) unpivoted( monthName, sales );

Et récupérez les données non archivées ...

Vous pouvez le faire avec OLAP . Voici un autre lien vers la documentation MSDN sur le sujet .

Avec OLAP, vous pouvez créer un cube avec les informations dont vous disposez et la présentation dont vous avez besoin.

Si vous ne souhaitez pas utiliser cette méthode, vous devrez créer des tables récapitulatives avec .NET, Java, TransacSQL ou votre langue préférée pour manipuler les données SQLServer.

Pour transposer facilement des colonnes en lignes avec ses noms, vous devez utiliser XML. Dans mon blog, je décrivais cet exemple avec l'exemple suivant: Lien

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top