订阅更新

直接或间接向 CEO 汇报的人:固定层级的多次自连接

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

LeetCode 1270 · 多级自连接、层级关系、递归 CTE

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

面试怎么回答

题目限定最多三层,我可以把员工表自连接三次,任一层经理是 1 就保留,再排除 CEO 本人。更通用的是递归 CTE:锚点是直接汇报给 CEO 的人,递归部分不断找「经理在结果集里」的员工,层数不限。要注意 CEO 自己汇报给自己,锚点里必须排除,否则会死循环。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

员工表记录每个人的直属经理,CEO 的 ID 是 1(CEO 的经理也是自己)。找出所有直接或间接向 CEO 汇报的员工 ID,题目保证中间最多隔三层经理。

表结构

  • Employees:employee_id(主键)、employee_name、manager_id

思路

层级有上限时,可以连续自连接:员工 a 的经理是 b,b 的经理是 c,只要 a、b、c 任一层的经理是 CEO,a 就向 CEO 汇报。最后排除 CEO 本人。层级不固定时,用递归 CTE 从 CEO 往下逐层展开,更通用。

参考解法

select employee_id
from 
(
select a.employee_id
from Employees a 
left join Employees b on a.manager_id = b.employee_id
left join Employees c on b.manager_id = c.employee_id
where a.manager_id=1 or b.manager_id=1  or c.manager_id=1
)t1
where employee_id!=1

另一种写法:递归 CTE:不限层数

WITH RECURSIVE sub AS (
  SELECT employee_id FROM Employees WHERE manager_id = 1 AND employee_id != 1
  UNION ALL
  SELECT e.employee_id FROM Employees e JOIN sub s ON e.manager_id = s.employee_id
)
SELECT employee_id FROM sub

易错点

  • CEO 的经理是自己,不排除的话会把 CEO 本人也算进去,递归写法里还可能死循环。
刷题进度保存在当前浏览器