SQL Server Add grand total

tp5buhyn  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(99)

I can't seem to figure out here is how to add that grand total line. I tried rollup and group sets but it just doubled the cumsum and the sumprice which I don't want.

This is what I need to mimick:

This is what I have so far:

SELECT
    YEAR(s.OrderDate) AS Year,
    MONTH(s.OrderDate) AS Month,
    SUM(sd.UnitPrice) AS Sum_Price,
    SUM(SUM(sd.UnitPrice)) OVER (PARTITION BY YEAR(OrderDate) ORDER BY MONTH(OrderDate)) AS CumSum
FROM
    Sales.SalesOrderDetail sd
JOIN Sales.SalesOrderHeader s ON s.SalesOrderID = sd.SalesOrderID
GROUP BY
    YEAR(s.OrderDate), MONTH(s.OrderDate)
ORDER BY
    Year, Month;

I am using AdventureWorks2019

cgh8pdjw

cgh8pdjw1#

You can use GROUPING SETS for this. The GROUPING function will tell you if a column has been grouped up in that row. It returns 0 for a non-aggregated row, and 1 for a rollup.

SELECT
    YEAR(s.OrderDate) AS Year,
    IIF(GROUPING(MONTH(s.OrderDate)) = 0,
        CAST(MONTH(s.OrderDate) AS varchar(20)),
        'grand_total'
    ) AS Month,
    CASE WHEN GROUPING(MONTH(s.OrderDate) = 0 THEN SUM(sd.UnitPrice) END AS Sum_Price,
    SUM(SUM(sd.UnitPrice)) OVER (PARTITION BY YEAR(OrderDate), GROUPING(Month)
        ORDER BY MONTH(OrderDate) ROWS UNBOUNDED PRECEDING) AS CumSum
FROM
    Sales.SalesOrderDetail sd
JOIN Sales.SalesOrderHeader s ON s.SalesOrderID = sd.SalesOrderID
GROUP BY GROUPING SETS (
    (YEAR(s.OrderDate), MONTH(s.OrderDate)),
    (YEAR(s.OrderDate)
)
ORDER BY
    YEAR(s.OrderDate),
    GROUPING(Month),
    MONTH(s.OrderDate);

You can also use a partial ROLLUP , although it's less clear what's going on. It compiles to the same thing, so efficiency will be the same. You can still use GROUPING() with this method.

GROUP BY
    YEAR(s.OrderDate),
    ROLLUP(MONTH(s.OrderDate))
agxfikkp

agxfikkp2#

I don't use this often so this might be off (I tend to let the client code or reporting tool handle the summaries), but try ROLLUP like this:

SELECT
    YEAR(s.OrderDate) AS Year,
    MONTH(s.OrderDate) AS Month,
    SUM(sd.UnitPrice) AS Sum_Price,
    SUM(SUM(sd.UnitPrice)) OVER (PARTITION BY YEAR(OrderDate) ORDER BY MONTH(OrderDate)) AS CumSum
FROM
    Sales.SalesOrderDetail sd
JOIN Sales.SalesOrderHeader s ON s.SalesOrderID = sd.SalesOrderID
GROUP BY
    ROLLUP(MONTH(s.OrderDate)), YEAR(s.OrderDate)
ORDER BY
    Year, Month;

相关问题