如何查询各职业薪资最高的员工?现有SQL查询报错求助
问题排查与解决方案
我来帮你分析下这段SQL的问题,再给你几个可行的实现方案~
原SQL的错误点
- GROUP BY后的字段选择违规:你按
Profession分组后直接SELECT EmployeeID不符合SQL标准逻辑(部分数据库关闭严格模式可能不报错,但这不是正确写法)。一个职业对应多个员工,EmployeeID既不是分组字段也不是聚合函数,数据库无法确定要返回哪个员工的ID。 - HAVING子句条件无效:
HAVING MAX(Salary) = Salary的逻辑不成立,HAVING是对分组后的聚合结果做筛选,MAX(Salary)是整个职业组的最高薪资,而Salary是单条记录的行级字段,两者不在同一层级,没法直接比较。
正确实现方案
方案一:子查询关联法(兼容绝大多数数据库)
先通过子查询算出每个职业的最高薪资,再和原表关联匹配出对应员工:
SELECT e.* FROM Employee e INNER JOIN ( -- 先获取每个职业的最高薪资 SELECT Profession, MAX(Salary) AS MaxSalary FROM Employee GROUP BY Profession ) p ON e.Profession = p.Profession AND e.Salary = p.MaxSalary;
方案二:窗口函数法(适合MySQL8+、PostgreSQL、SQL Server等支持窗口函数的数据库)
用RANK()窗口函数给每个职业的员工按薪资降序排名,取排名为1的员工(如果有多个薪资相同的最高薪员工,都会被保留):
SELECT * FROM ( SELECT *, -- 按职业分组,薪资降序排名 RANK() OVER (PARTITION BY Profession ORDER BY Salary DESC) AS SalaryRank FROM Employee ) ranked WHERE SalaryRank = 1;
⚠️ 注意:不要用ROW_NUMBER(),它会给同薪资的员工分配不同排名,可能漏掉部分最高薪员工;DENSE_RANK()效果和RANK()一致,也可以使用。
方案三:EXISTS子查询法
逻辑是:找出同一职业中没有其他员工薪资比他更高的员工,也就是该职业的最高薪员工:
SELECT e1.* FROM Employee e1 WHERE NOT EXISTS ( SELECT 1 FROM Employee e2 WHERE e2.Profession = e1.Profession AND e2.Salary > e1.Salary );
内容的提问来源于stack exchange,提问作者Yesudass Moses
相关产品推荐
相关产品推荐

