如何在MS SQL中查询每个季度的支出总额TOP3?
查询每个季度支出总额TOP3数据
我需要查询每个季度的支出总额TOP3数据,但当前代码会输出每个季度的所有支出记录,只想保留每个季度排名前三的支出总额。
原代码:
SELECT SUM(f.Spend) AS Total_Spend, e.expenset_id,e.[Expense Type], ROW_NUMBER() OVER(PARTITION BY e.expenset_id ORDER BY SUM(f.Spend) DESC) Rank, CASE WHEN DATEPART(mm,f.Date) IN (4,5,6) THEN 'Q2' WHEN DATEPART(mm,f.Date) IN (7,8,9) THEN 'Q3' WHEN DATEPART(mm,f.Date) IN (10,11,12) THEN 'Q4' ELSE 'Q1' END AS Quarter FROM fact_tbl f JOIN expense_type e ON f.expenset_id=e.expenset_id GROUP BY e.[Expense Type],e.expenset_id,DATEPART(mm,f.Date) ORDER BY SUM(f.Spend) DESC
问题分析
你的代码存在两个核心问题:
- 分组时用了
DATEPART(mm,f.Date),会把同一个季度的不同月份拆成独立分组,无法得到季度维度的总支出 - 排名的分区字段是
e.expenset_id,是按费用类型分组排名,而非按季度分区取每个季度的TOP3
修正后的代码
WITH QuarterlyExpenses AS ( SELECT SUM(f.Spend) AS Total_Spend, e.expenset_id, e.[Expense Type], CASE WHEN DATEPART(mm, f.Date) IN (4,5,6) THEN 'Q2' WHEN DATEPART(mm, f.Date) IN (7,8,9) THEN 'Q3' WHEN DATEPART(mm, f.Date) IN (10,11,12) THEN 'Q4' ELSE 'Q1' END AS Quarter FROM fact_tbl f JOIN expense_type e ON f.expenset_id = e.expenset_id GROUP BY e.expenset_id, e.[Expense Type], -- 按季度分组,而非按月 CASE WHEN DATEPART(mm, f.Date) IN (4,5,6) THEN 'Q2' WHEN DATEPART(mm, f.Date) IN (7,8,9) THEN 'Q3' WHEN DATEPART(mm, f.Date) IN (10,11,12) THEN 'Q4' ELSE 'Q1' END ) SELECT * FROM ( SELECT *, ROW_NUMBER() OVER(PARTITION BY Quarter ORDER BY Total_Spend DESC) AS Rank FROM QuarterlyExpenses ) ranked WHERE Rank <= 3 ORDER BY Quarter, Rank;
修正说明
- 先用CTE
QuarterlyExpenses按季度+费用类型分组,计算每个费用类型在对应季度的总支出,确保分组维度是季度而非月份 - 在子查询中,用
PARTITION BY Quarter按季度分区,按总支出降序生成排名 - 最后过滤出排名≤3的记录,得到每个季度的TOP3支出总额
如果需要处理并列排名(比如多个费用类型总支出相同,都算TOP3),可以把ROW_NUMBER()换成DENSE_RANK(),相同金额会得到相同排名,不会被挤掉。
内容的提问来源于stack exchange,提问作者Umar Usman
相关产品推荐
相关产品推荐

