我有一张这样的表:
SaleID Region Customer OrderAmt
1 North Keesha 10
2 West Mary 10
3 North Winston 10
4 North John 10
5 North Keesha 10
6 West John 10
7 West Mary 10
8 South John 10
使用SQL Server 2012,选择每个地区最高订购客户的最佳方式是什么,以及客户和地区的总数,即:
Region Customer CustAmt RegAmt
North Keesha 20 40
West Mary 20 30
South John 10 10
虽然多个地区可能包含相同的名称,但我们希望CustAmt
仅为每个地区内的名称总数,而不是跨地区(即最后一行,约翰在南部地区的总数)是10,而不是30)。
答案 0 :(得分:2)
使用CTE:
WITH cte AS (
SELECT Region, Customer
, sum(OrderAmt) AS CustAmt
, sum(sum(OrderAmt)) OVER (PARTITION BY Region) AS RegAmt
, row_number() OVER (PARTITION BY Region ORDER BY sum(OrderAmt) DESC) AS rn
FROM tbl
GROUP BY Region, Customer
)
SELECT Region, Customer, CustAmt, RegAmt
FROM cte
WHERE rn = 1;
或者,与子查询相同:
SELECT Region, Customer, CustAmt, RegAmt
FROM (
SELECT Region, Customer
, sum(OrderAmt) AS CustAmt
, sum(sum(OrderAmt)) OVER (PARTITION BY Region) AS RegAmt
, row_number() OVER (PARTITION BY Region ORDER BY sum(OrderAmt) DESC) AS rn
FROM tbl
GROUP BY Region, Customer
) sub
WHERE rn = 1;
关键功能是聚合上的窗口函数,因此我们只需要单个 CTE /子查询。
答案 1 :(得分:1)
在一个选择中:
select top 1 with ties
Region ,
Customer ,
CustAmt = sum(OrderAmt),
RegAmt = sum(sum(OrderAmt)) over (partition by Region)
from
your_table
group by
Region,
Customer
order by
row_number() over(partition by Region order by sum(OrderAmt) desc);
<强> SQL Fiddle 强>
答案 2 :(得分:0)
您可以使用多个CTE
和窗口函数:
WITH Cte AS(
SELECT *,
CustAmt = SUM(OrderAmt) OVER(PARTITION BY Customer, Region),
RegAmt = SUM(OrderAmt) OVER(PARTITION BY Region)
FROM Sales
),
CteFinal AS(
SELECT *,
rn = ROW_NUMBER() OVER(PARTITION BY Region ORDER BY CustAmt DESC)
FROM Cte
)
SELECT
Region, Customer, CustAmt, RegAmt
FROM CteFinal WHERE rn = 1