简体   繁体   中英

How do I sum over multiple criteria in T-SQL?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM