Oracle SQL使用SUM后报ORA-00979非GROUP BY表达式错误求助
错误原因
ORA-00979报错的核心是SQL执行顺序和GROUP BY的规则冲突:
- SQL的执行顺序为:关联/过滤 -> GROUP BY聚合 -> 窗口函数计算
- 你添加
SUM(A.AMT)后引入了GROUP BY a.ID,分组后的结果集仅保留分组键a.ID和聚合计算后的AMT两个字段 - 窗口函数
RANK() OVER (PARTITION BY a.ID ORDER BY b.NO DESC)中用到的b.NO既不在GROUP BY分组键中,也没有被聚合函数处理,分组后该字段不存在,因此触发报错 - 未加SUM时没有GROUP BY逻辑,关联后的结果集存在
b.NO字段,所以可以正常运行
解决方案
根据你的业务需求,可以选择以下两种改法:
方案1:先筛选排名再聚合(适用场景:需要取每个ID下b.NO最大的行再求和AMT)
先完成关联过滤和排名计算,筛选出排名为1的行后再做聚合,避免分组后缺少字段:
SELECT ID, SUM(AMT) AS AMT FROM ( SELECT a.ID, a.AMT, RANK() OVER (PARTITION BY a.ID ORDER BY b.NO DESC) AS rnk FROM TBL1 A JOIN TBL2 B ON a.ID = b.ID AND b.DATE <= a.DATE WHERE b.CD = 'AB' AND a.DESC = 'P' AND a.TYP_DESC = 'SEC' AND a.actg_prd_id BETWEEN TO_CHAR(ADD_MONTHS(TO_DATE('&&DATE','YYMM'),-2),'YYMM') AND '&&DATE' ) t WHERE rnk = 1 GROUP BY ID;
方案2:聚合b.NO后再做窗口排序(适用场景:需要先按ID聚合所有行的AMT,取每个ID的最大b.NO做排序)
对窗口函数ORDER BY后的b.NO添加聚合函数,保证分组后该字段可被识别:
SELECT * FROM ( SELECT a.ID, SUM(A.AMT) AS AMT, RANK () OVER (PARTITION BY a.ID ORDER BY MAX(b.NO) DESC) AS rnk FROM TBL1 A JOIN TBL2 B ON a.ID = b.ID AND b.DATE <= a.DATE WHERE b.CD = 'AB' AND a.DESC = 'P' AND a.TYP_DESC = 'SEC' AND a.actg_prd_id BETWEEN TO_CHAR(ADD_MONTHS(TO_DATE('&&DATE','YYMM'),-2),'YYMM') AND '&&DATE' GROUP BY a.ID ) a WHERE a.rnk = 1
注:该方案中因为PARTITION BY的键和GROUP BY的键都是a.ID,每个分组的rnk固定为1,可根据实际业务判断是否需要保留排名逻辑
内容的提问来源于stack exchange,提问作者ace123
相关产品推荐
相关产品推荐

