SQL按工作地点分组统计最高薪资时如何关联获取对应员工姓名
问题原因说明
你之前的写法没有达到预期,核心问题在于:把ename加入GROUP BY字段后,分组维度从原本的“按工作地点聚合”变成了“按工作地点+员工姓名逐行聚合”。每个分组最多对应单条员工记录,此时计算max(sal)得到的根本不是地点维度的最高薪资,就是每个员工自身的工资,最终结果自然会把全表所有条目都返回,完全偏离需求。
可行实现方案
方案1:窗口函数实现(优先推荐,适配当前所有主流数据库)
这种写法逻辑清晰,不需要重复关联原表,还能灵活处理同薪并列的场景:
WITH emp_sal_ranked AS ( SELECT e.sal, d.loc AS Location, e.ename AS names, -- 按工作地点划分分区,按薪资从高到低排序,同薪员工会得到相同排名 RANK() OVER (PARTITION BY d.loc ORDER BY e.sal DESC) AS rank_num FROM dept d INNER JOIN emp e ON d.deptno = e.dept ) SELECT sal AS Salary, Location, names FROM emp_sal_ranked WHERE rank_num = 1
- 如果业务上遇到同一地点多人拿相同最高薪时,只需要取任意一个员工展示,把代码里的
RANK()换成ROW_NUMBER()即可;如果需要把所有并列最高薪的员工都列出来,保留RANK()就可以实现。
方案2:适配低版本无窗口函数的数据库的写法
如果使用的是不支持窗口函数的老版本数据库(比如MySQL 5.x及更早版本),可以先聚合算出每个地点的最高薪资基准值,再把这个结果关联回原始的员工、部门表,匹配到对应拿最高薪的员工:
SELECT e.sal AS Salary, d.loc AS Location, e.ename AS names FROM dept d INNER JOIN emp e ON d.deptno = e.dept -- 关联提前算好的各地点最高薪值 INNER JOIN ( SELECT d2.loc, MAX(e2.sal) AS max_sal_per_loc FROM dept d2 INNER JOIN emp e2 ON d2.deptno = e2.dept GROUP BY d2.loc ) loc_sal_benchmark ON d.loc = loc_sal_benchmark.loc AND e.sal = loc_sal_benchmark.max_sal_per_loc
注意:关联时必须同时匹配地点和薪资,避免错误匹配其他地点的同薪员工
内容的提问来源于stack exchange,提问作者vinicius viera
相关产品推荐
相关产品推荐

