J'ai deux tableaux avec des données
TABLEAU 1
---------------------------------------------------
| SALEID | SOLDBY | SALEPRICE | MARGIN | DATE |
| 1 | 'aa' | 10,000 | 10 | 2013-1-1 |
| 2 | 'bb' | 25,000 | 5 | 2013-5-1 |
TABLEAU 2
---------------------------------------------------
| SALEITEMID | SALEID | SALEPRICE | CATEGORY |
| 1 | 1 | 6,000 | BOOKS |
| 2 | 1 | 4,000 | PRINTING |
| 3 | 2 | 5,000 | BOOKS |
| 4 | 2 | 12,000 | PRINTING |
| 5 | 2 | 8,000 | DVD |
J'ai besoin d'une requête qui produira
TAB
--------------------------------------------------------------------------------
| SALEID | SOLDBY | SALEPRICE | MARGIN | DATE | BOOKS | PRINTING | DVD
| 1 | 'aa' | 10,000 | 10 | 2013-1-1 | 6,000 | 4,000 | 0
| 2 | 'bb' | 25,000 | 5 | 2013-5-1 | 5,000 | 12,000 | 8,000
Je suis assez nouveau dans le pivot et je ne sais pas si le pivot est le chemin à parcourir pour cela ou non.
Cela devrait fonctionner:
WITH Sales AS (
SELECT
S.SaleID,
S.SoldBy,
S.SalePrice,
S.Margin,
S.Date,
I.SalePrice,
I.Category
FROM
dbo.Sale S
INNER JOIN dbo.SaleItem I
ON S.SaleID = I.SaleID
)
SELECT *
FROM
Sales
PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
;
Ou alternativement:
SELECT
S.SaleID,
S.SoldBy,
S.SalePrice,
S.Margin,
S.Date,
I.Books,
I.Printing,
I.DVD
FROM
dbo.Sale S
INNER JOIN (
SELECT *
FROM
(SELECT SaleID, SalePrice, Category FROM dbo.SaleItem) I
PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
) I ON S.SaleID = I.SaleID
;
Ceux-ci ont le même jeu de résultats et peuvent en fait être traités de la même manière par l'optimiseur de requête, mais peut-être pas. La grande différence entre en jeu lorsque vous commencez à mettre des conditions sur la table Sale
: vous devez tester et voir quelle requête fonctionne mieux.
Puis-je suggérer, cependant, que vous fassiez le pivotement dans la couche de présentation? Si, par exemple, vous utilisez SSRS, il est assez facile d'utiliser un contrôle matriciel qui fera tout le pivotement pour vous. C'est mieux, car alors si vous ajoutez un nouveau Category
, vous n'aurez pas à modifier tout votre code SQL!
Il existe un moyen de trouver dynamiquement les noms de colonnes à pivoter, mais cela implique un SQL dynamique. Je ne le recommande pas vraiment non plus, même si c'est possible.
Une autre façon dont pourrait fonctionner serait de prétraiter cette requête, c'est-à-dire de définir un déclencheur sur la table Category
qui réécrit une vue à contenir toutes les catégories existantes qui existent. Cela résout beaucoup d'autres problèmes que j'ai mentionnés, mais encore une fois, il est préférable d'utiliser la couche de présentation.
Remarque: si vos noms de colonnes (qui étaient auparavant des valeurs) ont des espaces, sont des nombres ou commencent par un nombre, ou ne sont pas des identifiants valides, vous devez les citer entre crochets comme dans PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P
. Vous pouvez également modifier les valeurs avant qu'elles n'atteignent la partie PIVOT
de la requête pour ajouter des lettres ou supprimer des espaces, afin que la liste des colonnes n'ait pas besoin d'être échappée. Pour plus d'informations à ce sujet, consultez les règles relatives aux identificateurs dans SQL Server.