Това трябва да работи:
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
;
Или алтернативно:
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
;
Те имат еднакъв набор от резултати и всъщност могат да бъдат третирани по същия начин от оптимизатора на заявки, но вероятно не. Голямата разлика се проявява, когато започнете да поставяте условия на Sale
таблица—трябва да тествате и да видите коя заявка работи по-добре.
Забележка:това е от решаващо значение, когато използвате PIVOT
че са налични само колоните, които трябва да бъдат част от резултантния изход. Ето защо горните две заявки имат допълнителни извлечени подзаявки за таблица (SELECT ...)
така че да се показват само определени колони. Всички колони, които са налични за преглед от PIVOT
които не са изброени в обобщения израз, имплицитно ще бъдат групирани и включени в крайния изход. Това вероятно няма да е това, което искате.
Мога ли обаче да ви предложа да направите завъртането в презентационния слой? Ако, например, използвате SSRS, е доста лесно да използвате матричен контрол, който ще извърши цялото завъртане вместо вас. Това е най-добре, защото тогава, ако добавите нова Category
, няма да трябва да променяте целия си SQL код!
Има начин за динамично намиране на имената на колоните за завъртане, но той включва динамичен SQL. Аз също не препоръчвам това като най-добрия начин, въпреки че е възможно.
Друг начин, който може работата би била да се обработи предварително тази заявка – което означава да се зададе тригер на Category
таблица, която пренаписва изглед, за да съдържа всички съществуващи категории, които съществуват. Това решава много от другите проблеми, които споменах, но отново, използването на презентационния слой е най-добро.
Забележка :Ако имената на вашите колони (които преди бяха стойности) имат интервали, са числа или започват с число, или по друг начин не са валидни идентификатори, трябва да ги поставите в кавички с квадратни скоби, както в PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P
. Като алтернатива можете да промените стойностите, преди да стигнат до PIVOT
част от заявката за добавяне на някои букви или премахване на интервали, така че списъкът с колони да не се нуждае от екраниране. За повече информация относно това вижте правилата за идентификатори в SQL Server.