I'm trying to improve on my very basic SQL querying skills and am using the AdventureWorks2012 sample database in SQL Server 2012. I have used SUM() OVER(PARTITION BY)
like this:
SELECT DISTINCT
SUM(SubTotal) OVER (PARTITION BY CustomerID), CustomerID
FROM
Sales.SalesOrderHeader
To get the total sales value for each customer, however I'd like to sum the SubTotal
by customer & year using YEAR(OrderDate)
to extract just the year portion of the order date.
Firstly it appears that I can't use the year portion of the order date to sum by year independently of customer so this approach isn't going to work anyhow.
Secondly I can't see any way to use multiple partition criteria.
I suspect that my inexperience is leading me to think about this in the wrong way so a theoretical approach would be as useful as a specific solution.
I guess I'm looking for something that is functionally similar to Excel's SUMIFS()
function
First, the correct way to write your query is:
SELECT CustomerID, SUM(SubTotal)
FROM Sales.SalesOrderHeader
GROUP BY CustomerID;
Using SELECT DISTINCT
with window functions is clever. But, it overcomplicates the query, can have poorer performance, and is confusing to anyone reading it.
To get the information by year (for each customer), just add that to the SELECT
and GROUP BY
:
SELECT CustomerID, YEAR(OrderDate) as yyyy, SUM(SubTotal)
FROM Sales.SalesOrderHeader
GROUP BY CustomerID, YEAR(OrderDate)
ORDER BY CustomerId, yyyy;
If you actually want to get separate rows with subtotals, then study up on GROUPING SETS
and ROLLUP
. These are options to the GROUP BY
.
You should use group by
instead of PARTITION BY
whenever you need an aggregate ( sum/count/max
) against a specific column like (customerid) as following
select customerId, sum(subTotal)
FROM sales.salesOrderHeader
group by customerId
Edit : including missing requirement of date (response to comment)
If you want calculation against more than one column, you still can do it same way. Just add the date
in group by clause as group by customerId, saleDate
select customerId, sum(subTotal)
,saleDate //=> you can miss it (date) from selection if you want to
FROM sales.salesOrderHeader
group by customerId, saleDate
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.