按部门查询最高平均薪资显示department_id报ORA-00937如何解决
报错原因分析
你遇到的ORA-00937报错的核心逻辑是SQL聚合查询的层级冲突:
- 你执行
GROUP BY DEPARTMENT_ID之后,查询的第一层聚合会为每个部门生成1行对应的AVG(SALARY)结果 - 嵌套聚合函数
MAX(AVG(SALARY))会对所有部门的平均薪资做第二次聚合,最终只会返回1行全局最大值结果 - 此时SELECT子句中的
DEPARTMENT_ID没有被包裹在聚合函数中,也没有对应更高层级的GROUP BY规则,Oracle无法确定这个唯一的最大值对应哪个部门的ID,因此触发单组分组函数不匹配的报错。
错误写法的问题
你想在同一层SELECT中同时返回*跨部门聚合的唯一最大值、和部门维度的ID,不符合SQL分组聚合的语法规则:嵌套聚合执行后结果集已经从多行(每个部门一行)压缩为单行(全局最大值一行),无法直接对应原分组维度的字段值。
可行解决方案
方案1:子查询排序取TOP1(兼容所有Oracle版本,适合唯一最大值场景)
SELECT DEPARTMENT_ID, AVG_SAL FROM ( -- 先计算每个部门的平均薪资,按薪资降序排序 SELECT DEPARTMENT_ID, AVG(SALARY) AVG_SAL FROM EMPLOYEE GROUP BY DEPARTMENT_ID ORDER BY AVG_SAL DESC ) WHERE ROWNUM = 1;
方案2:开窗函数(支持多部门并列最高的场景)
SELECT DEPARTMENT_ID, AVG_SAL FROM ( SELECT DEPARTMENT_ID, AVG(SALARY) AVG_SAL, -- 按部门平均薪资排序生成排名 RANK() OVER(ORDER BY AVG(SALARY) DESC) RN FROM EMPLOYEE GROUP BY DEPARTMENT_ID ) -- 取排名第一的所有部门,多个部门薪资并列最高也会全部返回 WHERE RN = 1;
方案3:HAVING匹配全局最大值
SELECT DEPARTMENT_ID, AVG(SALARY) AVG_SAL FROM EMPLOYEE GROUP BY DEPARTMENT_ID -- 过滤出部门平均薪资等于全局最高平均薪资的记录 HAVING AVG(SALARY) = ( SELECT MAX(AVG(SALARY)) FROM EMPLOYEE GROUP BY DEPARTMENT_ID );
内容的提问来源于stack exchange,提问作者Vaiebhav Patil
相关产品推荐
相关产品推荐

