每个部门工资最高的员工:并列第一都要
LeetCode 184 · 分组 Top 1、RANK、关联维表
面试怎么回答
分组 Top N 我一般用窗口函数:关联部门后 RANK() OVER (PARTITION BY 部门 ORDER BY Salary DESC),取 rk = 1,并列最高都会保留。不用窗口函数的话,可以先算每个部门的最高工资,再用 (部门, 工资) 回关联员工表。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
员工表有部门 ID,部门表有部门名称。找出每个部门里工资最高的员工,输出部门名、员工名和工资;如果多人并列最高,都要输出。
表结构
- Employee:Id(主键)、Name、Salary、DepartmentId
- Department:Id(主键)、Name
思路
分组取最大值的经典题。先关联部门表拿到部门名,再按部门分区、工资降序排名,取排名为 1 的行。因为并列最高都要保留,用 RANK 或 DENSE_RANK,不能用 ROW_NUMBER。
参考解法
select Department,Employee,Salary
from (
select d.Name Department,e.Name Employee, e.Salary,
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 = 1
易错点
- 用 ROW_NUMBER 只会随机留下并列者中的一个。
- 用
GROUP BY DepartmentId再 SELECT Name 拿不到正确的员工名(非聚合列取值不确定),要么用窗口函数,要么用 (DepartmentId, MAX(Salary)) 回表关联。