直接或间接向 CEO 汇报的人:固定层级的多次自连接
LeetCode 1270 · 多级自连接、层级关系、递归 CTE
面试怎么回答
题目限定最多三层,我可以把员工表自连接三次,任一层经理是 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 本人也算进去,递归写法里还可能死循环。