Das sollte funktionieren:
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
;
Oder alternativ:
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
;
Diese haben die gleiche Ergebnismenge und können vom Abfrageoptimierer tatsächlich gleich behandelt werden, möglicherweise aber nicht. Der große Unterschied kommt zum Tragen, wenn Sie anfangen, Bedingungen für den Sale
festzulegen Tabelle – Sie sollten testen und sehen, welche Abfrage besser funktioniert.
Hinweis:Es ist entscheidend, wenn Sie PIVOT
verwenden dass nur die Spalten verfügbar sind, die Teil der resultierenden Ausgabe sein sollen. Aus diesem Grund haben die beiden obigen Abfragen zusätzliche abgeleitete Tabellenunterabfragen (SELECT ...)
sodass nur bestimmte Spalten angezeigt werden. Alle Spalten, die für PIVOT
verfügbar sind die nicht im Pivot-Ausdruck aufgeführt sind, werden implizit gruppiert und in die endgültige Ausgabe aufgenommen. Das ist wahrscheinlich nicht das, was Sie wollen.
Darf ich jedoch vorschlagen, dass Sie das Pivotieren in der Präsentationsebene vornehmen? Wenn Sie beispielsweise SSRS verwenden, ist es ganz einfach, eine Matrixsteuerung zu verwenden, die das gesamte Pivotieren für Sie übernimmt. Das ist am besten, denn dann fügen Sie eine neue Category
hinzu , müssen Sie nicht Ihren gesamten SQL-Code ändern!
Es gibt eine Möglichkeit, die zu pivotierenden Spaltennamen dynamisch zu finden, aber dazu gehört dynamisches SQL. Ich empfehle das auch nicht wirklich als den besten Weg, obwohl es möglich ist.
Ein anderer Weg, der könnte Die Arbeit wäre, diese Abfrage vorzuverarbeiten – das heißt, einen Trigger auf die Category
zu setzen Tabelle, die eine Ansicht so umschreibt, dass sie alle vorhandenen Kategorien enthält. Dies löst viele der anderen Probleme, die ich erwähnt habe, aber auch hier ist es am besten, die Präsentationsebene zu verwenden.
Hinweis :Wenn Ihre Spaltennamen (die früher Werte waren) Leerzeichen enthalten, Zahlen sind oder mit einer Zahl beginnen oder anderweitig keine gültigen Bezeichner sind, müssen Sie sie wie in PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P
. Alternativ können Sie die Werte ändern, bevor sie zum PIVOT
gelangen Teil der Abfrage, um einige Buchstaben voranzustellen oder Leerzeichen zu entfernen, sodass die Spaltenliste nicht maskiert werden muss. Weitere Informationen hierzu finden Sie in den Regeln für Identifikatoren im SQL-Server.