部门工资前三高:前三「档」而不是前三个人
LeetCode 185 · 分组 Top N、DENSE_RANK
面试怎么回答
题目要的是前三个工资档位,所以按部门分区、工资降序用 DENSE_RANK,取 rk <= 3。如果题目改成「前三个人」就用 ROW_NUMBER,「前三名且并列跳号」就用 RANK,三个函数的选择取决于业务对并列的定义。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
找出每个部门里工资排在前三档的所有员工。同样工资算同一档,比如 90、85、85、70,四个人都属于前三档。
表结构
- Employee:Id(主键)、Name、Salary、DepartmentId
- Department:Id(主键)、Name
思路
和部门最高工资是同一类题,只是 N 变成 3,而且要求的是前三个「不同工资」。所以必须用 DENSE_RANK:并列不跳号,前三档的人都能拿到。用 RANK 时 85 并列第二后下一档会变成第 4 名而被过滤掉。
参考解法
select Department,Employee,Salary
from (
select d.Name Department,e.Name Employee, e.Salary,
dense_rank() over(partition by d.id order by Salary desc) rk
from Employee e join Department d
on e.DepartmentId=d.id
)tmp
where rk <=3
易错点
- 用 RANK:90、85、85、70 会排成 1、2、2、4,工资 70 的人被漏掉。
- 用 ROW_NUMBER:并列的人只留下一个。