订阅更新

每个部门工资最高的员工:并列第一都要

SQL 实战 123 题 · 第 9 题 中等 约 2 分钟读完

LeetCode 184 · 分组 Top 1、RANK、关联维表

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

分组 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)) 回表关联。
刷题进度保存在当前浏览器