Oracle查询报错ORA-00937:需计算列计数与最大值计数并分组
解决ORA-00937错误:修正你的Oracle分组查询
你的查询抛出ORA-00937错误,核心原因是在count()聚合函数里嵌套了另一个聚合函数max(subVers.verNum)——Oracle不允许在同一个SELECT层级里这么用,因为max()是针对整个分组的聚合结果,没法作为每行的判断条件放在case里。
我先按最贴合原需求的逻辑给出修正方案:
修正后的查询(使用CTE)
WITH subj_stats AS ( SELECT subj.inventoryNum, EXTRACT(MONTH FROM subj.createDate) AS month, oolame.schoolCode, MAX(subVers.verNum) AS max_ver_num, -- 统计当前Subject下有delDate不为空的版本行数 COUNT(CASE WHEN subVers.delDate IS NOT NULL THEN 1 END) AS changed_count FROM Subjects subj INNER JOIN SubjectVersions subVers ON subVers.subjFk = subj.subjId INNER JOIN SchoolName oolame ON oolame.oolameId = subj.oolameFk -- 先按每个Subject分组,计算单个Subject的聚合值 GROUP BY subj.subjId, subj.inventoryNum, EXTRACT(MONTH FROM subj.createDate), oolame.schoolCode ) SELECT inventoryNum AS Inventory, month, schoolCode AS Code, -- 统计分组中最大版本号>0的Subject数量 COUNT(CASE WHEN max_ver_num > 0 THEN 1 END) AS deleted, -- 统计分组中所有有delDate的版本总行数 SUM(changed_count) AS changed FROM subj_stats -- 按你需要的维度最终分组 GROUP BY inventoryNum, month, schoolCode;
为什么原查询会报错?
原查询里的count(case when max(subVers.verNum) > 0 then 1 end)是语法错误:
max(subVers.verNum)是分组级别的聚合结果,它代表整个分组里的最大版本号,不是某一行的值。- 而
case语句是针对分组内的每一行进行判断的,你不能用一个分组级的聚合值去判断每一行,Oracle自然会抛出“不是单组分组函数”的错误。
调整逻辑的可选方案
如果你的deleted字段想统计的是分组中所有版本号>0的记录行数(而不是Subject数量),那可以简化查询,不需要子查询,只需要把max()去掉,直接判断每行的verNum:
SELECT subj.inventoryNum AS Inventory, EXTRACT(MONTH FROM subj.createDate) AS month, oolame.schoolCode AS Code, COUNT(CASE WHEN subVers.verNum > 0 THEN 1 END) AS deleted, COUNT(CASE WHEN subVers.delDate IS NOT NULL THEN 1 END) AS changed FROM Subjects subj INNER JOIN SubjectVersions subVers ON subVers.subjFk = subj.subjId INNER JOIN SchoolName oolame ON oolame.oolameId = subj.oolameFk GROUP BY subj.inventoryNum, EXTRACT(MONTH FROM subj.createDate), oolame.schoolCode;
但这个逻辑和你原查询里用max()的意图可能不一样,你可以根据实际需求选择。
内容的提问来源于stack exchange,提问作者GingerHead
相关产品推荐
相关产品推荐

