SQL使用ROLLUP与COALESCE实现按月份品牌分组统计及总计问题
错误原因
- 原语句
GROUP BY ROLLUP(PurchaseDate, Brand)是按完整日期而非月份分组,导致同一月份的同品牌数据被拆分到不同日期分组,出现大量多余空值条目。 - 仅用
COALESCE(Brand, 'Monthly Total')无法区分「月度汇总的Brand空值」和「全局汇总的Brand空值」,所以全局总计行也会错误显示为Monthly Total。
正确实现语句
SELECT CASE WHEN GROUPING(MONTH(PurchaseDate)) = 1 THEN '总计' ELSE CAST(MONTH(PurchaseDate) AS VARCHAR(2)) END AS Months, CASE WHEN GROUPING(MONTH(PurchaseDate)) = 1 THEN 'Grand Total' WHEN GROUPING(Brand) = 1 THEN 'Monthly Total' ELSE Brand END AS Brand, SUM(Price) AS TotalAmount FROM Purchase_Items GROUP BY ROLLUP(MONTH(PurchaseDate), Brand) ORDER BY MONTH(PurchaseDate), GROUPING(Brand)
逻辑说明
- 分组维度改为
ROLLUP(MONTH(PurchaseDate), Brand),生成三级分组:- 「月份+品牌」:对应单月单个品牌的采购总金额
- 「月份」:对应单个月份所有品牌的采购总金额(月度合计)
- 空维度:对应所有数据的全局总计
- 用
GROUPING()函数判断空值生成场景:- 当
GROUPING(Brand)=1且GROUPING(月份)=0时,为月度汇总行,Brand显示Monthly Total - 当
GROUPING(月份)=1时,为全局汇总行,Brand显示Grand Total
- 当
- 末尾加ORDER BY保证输出顺序符合阅读习惯,同月份数据排在一起,月度合计行放在对应月份所有品牌条目之后,全局总计行在最后。
内容的提问来源于stack exchange,提问作者Richard Johnson
相关产品推荐
相关产品推荐

