2017-07-27 1 views
2

Ist es möglich, auf mehreren aggregierten Spalten in SQL Server zu drehen? Ich habe die folgende Reihenfolge Tabelle:SQL Server-Pivot auf 2 (oder mehreren) Aggregaten

[ORDERS] 
| CustName | OrderedProduct | QtyOrdered | UnitCost | UnitPrice | OrderDate 
    Bob  | Canned Tuna |   6 |  11 |  14 | 21-12-2016 13:11:00 
    Steve | Canned Salmon |   2 |  15 |  19 | 03-11-2016 11:03:00 
    Bob  | Canned Tuna |   10 |  10 |  13 | 22-12-2016 10:43:00 
    Bob  | Canned Tuna |   4 |  9 |  10 | 13-11-2016 17:22:00 

Ich habe folgende Pivot-Abfrage, die mir eine Bestellmenge pro Produkt für Monate November/Dezember pro Kunde gibt:

SELECT CustName, OrderedProduct, [VOL Dec 2016], [VOL Nov 2016] FROM 
(
    SELECT CustName, OrderedProduct, QtyOrdered, 
    'VOL ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120) AS YearMonthVol 
    FROM [ORDERS] 
) src 
PIVOT 
(
    SUM(QtyOrdered) 
    FOR YearMonthVol IN ([VOL Dec 2016], [VOL Nov 2016]) 
) pvtvol 
WHERE CustName='Bob' 

Dies gibt dem, erwartet Ergebnis

CustName | OrderedProduct | VOL Dec 2016 | VOL Nov 2016 
Bob  | Canned Tuna |   16 |   4 

Was ich will, ist auch Pivot auf Margin so Ändern der src Abfrage:

SELECT CustName, OrderedProduct, QtyOrdered, 
    ((UnitPrice-UnitCost)*QtyOrdered) AS Margin, 
    'VOL ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120) AS YearMonthVol 
    'MAR ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120) AS YearMonthMar 
    FROM [ORDERS] 

ich folgende geänderte Abfrage versucht haben, eine zweite Dreh Zugabe

SELECT CustName, OrderedProduct, [VOL Dec 2016], [VOL Nov 2016], [MAR Dec 2016], [MAR Nov 2016] FROM 
(
    SELECT CustName, OrderedProduct, QtyOrdered, 
    ((UnitPrice-UnitCost)*QtyOrdered) AS Margin, 
    'VOL ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120) AS YearMonthVol 
    'MAR ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120) AS YearMonthMar 
    FROM [ORDERS] 
) src 
PIVOT 
(
    SUM(QtyOrdered) 
    FOR YearMonthVol IN ([VOL Dec 2016], [VOL Nov 2016]) 
) pvtvol 
PIVOT 
(
    SUM(Margin) 
    FOR YearMonthMar IN ([MAR Dec 2016], [MAR Nov 2016]) 
) pvtmar 
WHERE CustName='Bob' 

Die Tabelle würde ich ERWARTEN zu sehen ist

CustName | OrderedProduct | VOL Dec 2016 | VOL Nov 2016 | MAR Dec 2016 | MAR Nov 2016 
Bob  | Canned Tuna |   16 |   4 |   48 |   4 

Die Tabelle I tatsächlich siehe ist

CustName | OrderedProduct | VOL Dec 2016 | VOL Nov 2016 | MAR Dec 2016 | MAR Nov 2016 
Bob  | Canned Tuna |   16 |   NULL |   48 |   NULL 
Bob  | Canned Tuna |   NULL |   4 |   NULL |   4 

Also, der Drehpunkt am Rand scheint nicht angewendet zu werden, und ich bekomme eine Zeile für jede Bestellung. Ist das, was ich versuche zu erreichen, tatsächlich möglich mit der Methode, die ich versuche zu verwenden, oder wäre ich besser eine Kreuztabellenabfrage für VOL und MAR oder eine Mischung aus Pivot und Kreuztabellen (Pivot für VOL, Kreuztabelle für MAR?)

Jeder Rat sehr geschätzt.

+0

Fügen Sie eine 'GROUP BY CustName, OrderedProduct' in Ihrer zweiten Abfrage hinzu. –

+0

Zur Abfrage ** src **? Dasselbe Ergebnis, wenn ich das mache, und ich bin auch gezwungen, QtyOrdered in der GROUP BY – Gord

+0

Nein zur letzten Abfrage mit zwei Pivots aufzunehmen. Ich denke, das ist was fehlt. –

Antwort

2

Sie könnten vereinfachen Ihre Abfrage ein wenig

Beispiel

Select * 
From (
     Select A.CustName 
       ,A.OrderedProduct 
       ,B.* 
     From ORDERS A 
     Cross Apply (values ('VOL '+left(DateName(Month,OrderDate),3)+' '+DateName(Year,OrderDate), QtyOrdered) 
          ,('MAR '+left(DateName(Month,OrderDate),3)+' '+DateName(Year,OrderDate),((UnitPrice-UnitCost)*QtyOrdered)) 
        ) B (Item,Value) 
     Where CustName='Bob' 
    ) A 
Pivot (sum([Value]) For [Item] in ([VOL Dec 2016], [VOL Nov 2016],[MAR Dec 2016], [MAR Nov 2016])) p 

Returns

enter image description here

+0

Beat mich um ein paar Sekunden: D war Demo vorbereiten;) –

+0

@P ரதீபரதீப Das macht es zu einem guten Tag für mich. –

+0

Danke euch beiden. – Gord

1

Sie müssen UNPIVOT und Pivot

SELECT CustName, OrderedProduct, [VOL Dec 2016], [VOL Nov 2016], [MAR Dec 2016], [MAR Nov 2016] FROM 
(
    SELECT CustName, OrderedProduct,YearMonth,val 
    FROM [ORDERS] 
    cross apply (values ('VOL ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120),QtyOrdered),('MAR ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120),((UnitPrice-UnitCost)*QtyOrdered))) tc 
    (YearMonth,val) 
    WHERE CustName='Bob' 
) src 
PIVOT 
(
    SUM(val) 
    FOR YearMonth IN ([VOL Dec 2016], [VOL Nov 2016],[MAR Dec 2016], [MAR Nov 2016]) 
) pvtvol 

Die doppelte Datensätze in Ihr Ergebnis ist auf das Vorhandensein von QtyOrdered und Margin in Pivot-Quellabfrage durch. QtyOrdered und Margin müssen einzeln geschwenkt werden, um Dubletten zu vermeiden. Es muss so gemacht werden

;with QtyOrdered as 
(
SELECT CustName, OrderedProduct, [VOL Dec 2016], [VOL Nov 2016]FROM 
(
    SELECT CustName, OrderedProduct, QtyOrdered, 
    'VOL ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120) AS YearMonthVol 
    FROM [ORDERS] 
    WHERE CustName='Bob' 
) src 
PIVOT 
(
    SUM(QtyOrdered) 
    FOR YearMonthVol IN ([VOL Dec 2016], [VOL Nov 2016]) 
) pvtvol 
),Margin as 
(
    select * from (
SELECT CustName, OrderedProduct, ((UnitPrice-UnitCost)*QtyOrdered) AS Margin, 
    'MAR ' + CONVERT(CHAR(4), OrderDate, 100) + CONVERT(CHAR(4), OrderDate, 120) AS YearMonthMar 
    FROM [ORDERS] 
    ) a 
PIVOT 
(
    SUM(Margin) 
    FOR YearMonthMar IN ([MAR Dec 2016], [MAR Nov 2016]) 
) pvtmar 
WHERE CustName='Bob'  
) 
select * from QtyOrdered q 
join Margin m on q.CustName = m.CustName 
and q.OrderedProduct = m.OrderedProduct 
+0

Danke für die Erklärung, das macht jetzt vollkommen Sinn. – Gord

Verwandte Themen