使用GROUP BY ROLLUP计算列总计时出现结果重复该如何排查
问题原因
你遇到的"行重复"本质是ROLLUP语法的特性导致的,并非查询报错:
GROUP BY ROLLUP(列1,列2,列3)会按列的顺序生成所有前缀层级的聚合结果,总共有N+1种聚合层级(N是列数),你的写法会生成4种聚合层级:- 层级1:按
CLIENT_NUMBER,LINE_TYPE_HM,PR_TYP_C三个字段聚合,和你F2里的聚合结果一致 - 层级2:按
CLIENT_NUMBER,LINE_TYPE_HM两个字段聚合,PR_TYP_C返回null - 层级3:按
CLIENT_NUMBER一个字段聚合,LINE_TYPE_HM、PR_TYP_C都返回null - 层级4:全局总计,三个字段都返回null
- 层级1:按
- 加上你只对
CLIENT_NUMBER做了coalesce处理,另外两个字段的null值没有做标识,很容易把不同层级的聚合行误认为是重复行;另外你查询里已经固定了prn_cln_n = '242931',层级3和层级4的CLIENT_NUMBER都会被替换为TOTAL,这部分也会看起来是重复行。 - 另外也可以先排查CTE
TOTS的关联逻辑:actbl、actblc、swkl三个表关联如果存在一对多的关系,会导致基础数据本身重复,也会影响最终聚合结果。
解决方案
方案1:只保留明细聚合+全局总计(无中间层级,解决大部分"重复"问题)
把最外层的GROUP BY ROLLUP替换为GROUPING SETS,只指定你需要的聚合层级即可:
SELECT coalesce(CLIENT_NUMBER,'TOTAL') AS CLIENT_NUMBER ,LINE_TYPE_HM ,PR_TYP_C ,SUM(BILL_AMOUNT) BILL_AMOUNT FROM F2 group by grouping sets ( (CLIENT_NUMBER,LINE_TYPE_HM,PR_TYP_C), -- 原始明细聚合行 () -- 全局总计行 )
方案2:保留所有ROLLUP层级,标识聚合级别避免误判
用GROUPING()函数区分不同聚合层级,同时对维度字段的空值做统一标识:
SELECT coalesce(CLIENT_NUMBER,'TOTAL') AS CLIENT_NUMBER, CASE WHEN GROUPING(LINE_TYPE_HM) = 1 THEN '全类型' ELSE LINE_TYPE_HM END AS LINE_TYPE_HM, CASE WHEN GROUPING(PR_TYP_C) = 1 THEN '全PR类型' ELSE PR_TYP_C END AS PR_TYP_C, SUM(BILL_AMOUNT) AS BILL_AMOUNT, -- 聚合级别标识:0=原始明细 1=按客户+LINE_TYPE聚合 2=按客户聚合 3=全局总计 GROUPING(CLIENT_NUMBER) + GROUPING(LINE_TYPE_HM) + GROUPING(PR_TYP_C) AS AGG_LEVEL FROM F2 group by rollup (CLIENT_NUMBER,LINE_TYPE_HM,PR_TYP_C)
内容的提问来源于stack exchange,提问作者sm86
相关产品推荐
相关产品推荐

