我在Sales
SQL Server 2012
个表格
Use tempdb
Go
CREATE TABLE Sales (EmpId INT, Yr INT, Sales MONEY)
INSERT Sales VALUES(1, 2005, 12000)
INSERT Sales VALUES(1, 2006, 18000)
INSERT Sales VALUES(1, 2007, 25000)
INSERT Sales VALUES(2, 2005, 15000)
INSERT Sales VALUES(2, 2006, 6000)
INSERT Sales VALUES(3, 2006, 20000)
INSERT Sales VALUES(3, 2007, 24000)
我想创建一个包含此结果的报告:
/*
EmpId------ Yr----- SUM(Sales) BY EmpId, Yr---------- SUM(Sales) BY EmpId ----------SUM(Sales)
1 2005 12000.00 12000.00 12000.00
1 2006 18000.00 30000.00 30000.00
1 2007 25000.00 55000.00 55000.00
1 NULL 55000.00 55000.00
2 2005 15000.00 15000.00 70000.00
2 2006 6000.00 21000.00 76000.00
2 NULL 21000.00 76000.00
3 2006 20000.00 20000.00 96000.00
3 2007 24000.00 44000.00 120000.00
3 NULL 44000.00 120000.00
NULL NULL 120000.00
*/
我写了这样一个查询:
SELECT EmpId, Yr, SUM(Sales) AS Sales
FROM Sales
GROUP BY EmpId, Yr WITH ROLLUP
如何更改查询以获取更多列,例如abauve。
答案 0 :(得分:3)
在SQL Server 2012+中,您可以使用窗口函数执行累积求和。以下基本上可以满足您的需求:
SELECT EmpId, Yr, SUM(Sales) AS Sales,
SUM(case when Yr is not null then SUM(Sales) end) OVER
(PARTITION BY EmpId
Order By (case when Yr is null then 0 else 1 end) desc, Yr
),
SUM(case when yr is not null then SUM(SALES) end) OVER
(Order by EmpId, (case when Yr is null then 0 else 1 end) desc, Yr)
FROM Sales
GROUP BY EmpId, Yr WITH ROLLUP
ORDER BY (case when EmpId is null then 0 else 1 end) desc, empid,
(case when Yr is null then 0 else 1 end) desc, yr;
这很棘手,因为rollup
和窗口函数之间的相互作用需要小心。
Here是SQL小提琴。
编辑:
要修复最后一行的最后一个单元格,可以添加case
语句:
SELECT EmpId, Yr, SUM(Sales) AS Sales,
SUM(case when Yr is not null then SUM(Sales) end) OVER
(PARTITION BY EmpId
Order By (case when Yr is null then 0 else 1 end) desc, Yr
),
(case when yr is null and empid is null
then sum(case when yr is not null and empid is not null then sum(sales) end) over ()
else SUM(case when yr is not null then SUM(SALES) end) OVER
(Order by EmpId, (case when Yr is null then 0 else 1 end) desc, Yr)
end)
FROM Sales
GROUP BY EmpId, Yr WITH ROLLUP
ORDER BY (case when EmpId is null then 0 else 1 end) desc, empid,
(case when Yr is null then 0 else 1 end) desc, yr;