SQL问题:如何查询各部门最高薪资及对应员工姓名
解决各部门最高薪资及对应员工姓名的SQL查询问题
咱们先捋清楚你遇到的问题根源:
你写的第一句SQL select dept_id, name, max(salary) from SalaryTable group by salary 报错,核心有两个问题:
- 分组逻辑错误:你要的是各部门的最高薪资,所以应该按
dept_id分组,而非salary。按薪资分组完全偏离了你的需求方向。 - SQL语法规则限制:当使用
GROUP BY时,SELECT子句里的非聚合字段(比如这里的dept_id、name)必须要么出现在GROUP BY中,要么被聚合函数(如MAX()、MIN())包裹。你既没把这两个字段放到GROUP BY里,也没对它们用聚合函数,数据库无法确定返回哪些值,因此抛出了报错。
另外你提到的第二句SQL select dept_id, max(salary) as max_salary from SalaryTable group by salary 逻辑也不对——它是按薪资分组,得到的结果并不是各部门的最高薪资,而是每个薪资对应的部门和该薪资的最大值(其实就是薪资本身),完全不符合你的需求。
下面给你两种靠谱的解决办法,能精准得到你期望的结果:
方法一:子查询关联(兼容所有主流数据库)
先通过子查询算出每个部门的最高薪资,再关联原表匹配出对应的员工信息:
SELECT st.dept_id, st.name, st.salary AS max_salary FROM SalaryTable st INNER JOIN ( -- 子查询:按部门分组,得到每个部门的最高薪资 SELECT dept_id, MAX(salary) AS max_salary FROM SalaryTable GROUP BY dept_id ) dept_max ON st.dept_id = dept_max.dept_id AND st.salary = dept_max.max_salary;
这个语句逻辑很清晰:子查询先拿到每个部门的最高薪资数据,再通过部门ID和薪资值,把原表中对应的数据匹配出来,就能得到每个部门薪资最高的员工姓名。
方法二:窗口函数(适合支持窗口函数的数据库,如MySQL 8+、PostgreSQL、SQL Server等)
如果你的数据库支持窗口函数,用ROW_NUMBER()会更灵活,还能处理一个部门有多个员工薪资并列最高的情况:
SELECT dept_id, name, salary AS max_salary FROM ( SELECT dept_id, name, salary, -- 按部门分组,给每个部门的员工按薪资降序编号 ROW_NUMBER() OVER(PARTITION BY dept_id ORDER BY salary DESC) AS rn FROM SalaryTable ) ranked -- 取每个部门编号为1的记录(也就是薪资最高的那条) WHERE rn = 1;
如果遇到一个部门有多个员工薪资都是最高的,你可以把ROW_NUMBER()换成RANK()或者DENSE_RANK(),这样就能返回所有并列最高薪资的员工,而不会只返回其中一个。
内容的提问来源于stack exchange,提问作者Shobhit Mittal




