SQL Server output on 2 (or more) aggregates

Can I rotate multiple aggregated columns in SQL Server? I have the following order table:

[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

I have the following summary request that gives me the number of product orders per customer for the months of November / Dec:

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'

This gives the expected result.

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

What I want is also a field turn to change the src request to:

    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]

I tried the following modified query adding a second anchor element

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'

In the table, I would display EXPECT

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

Table i actually is

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

, , , , . , , , - VOL MAR - ( VOL, - MAR? )

.

+2
2

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

enter image description here

+2

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

QtyOrdered Margin . QtyOrdered Margin , . :

;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 
+1

Source: https://habr.com/ru/post/1692425/


All Articles