数据库查询需求:查找第5低薪资员工及各部门最高薪资员工
没问题,我来帮你解决这两个SQL查询问题,先整理好我们要操作的员工表数据:
员工表(
EMP)数据 | EMPID | NAME | DEPTID | SALARY |
|---|---|---|---|
| 101 | surendra | 201 | 1000 |
| 102 | narendra | 202 | 2000 |
| 103 | rajesh | 203 | 3000 |
| 104 | ramesh | 203 | 2000 |
| 105 | hanumanth | 202 | 10000 |
a) 查询薪资从低到高排序后第5位的员工
这个需求可以用窗口函数实现,这是当前主流数据库(MySQL 8+、PostgreSQL、Oracle、SQL Server等)都支持的通用方案,逻辑清晰:
SELECT EMPID, NAME, DEPTID, SALARY FROM ( SELECT EMPID, NAME, DEPTID, SALARY, ROW_NUMBER() OVER(ORDER BY SALARY ASC) AS salary_rank FROM EMP ) ranked_emps WHERE salary_rank = 5;
思路说明:
- 内层查询通过
ROW_NUMBER()给每个员工按薪资升序分配唯一的排名序号; - 外层直接筛选序号为5的记录,就是薪资第5低的员工。
如果是使用MySQL 5.x这类不支持窗口函数的老版本,也可以用LIMIT语法实现:
SELECT EMPID, NAME, DEPTID, SALARY FROM EMP ORDER BY SALARY ASC LIMIT 4, 1;
(LIMIT 4,1表示跳过前4条记录,直接取第5条)
b) 查询每个部门中薪资最高的员工
这里要注意:同一个部门可能存在多名员工薪资并列最高的情况,所以推荐用RANK()窗口函数来保留所有并列最高的记录,避免遗漏:
SELECT EMPID, NAME, DEPTID, SALARY FROM ( SELECT EMPID, NAME, DEPTID, SALARY, RANK() OVER(PARTITION BY DEPTID ORDER BY SALARY DESC) AS dept_sal_rank FROM EMP ) dept_ranked_emps WHERE dept_sal_rank = 1;
思路说明:
- 内层查询用
PARTITION BY DEPTID按部门分组,再给每个组内的员工按薪资降序排名; RANK()会给并列最高的员工分配相同的排名(比如部门内有两个员工薪资都是最高,他们的排名都会是1);- 外层筛选排名为1的记录,就能得到每个部门所有薪资最高的员工。
如果你的场景只需要每个部门返回一条最高薪资的员工(即使有并列),可以把RANK()换成ROW_NUMBER(),但这种方式会随机剔除并列的记录,所以更推荐用RANK()或者DENSE_RANK()(两者区别是DENSE_RANK()不会跳过排名序号,比如并列1之后下一个是2,而RANK()会跳过)。
内容的提问来源于stack exchange,提问作者ASHIS MANNA




