题目描述
(通过次数9,776 | 提交次数12,069,通过率81.00%)
员工表:Employees +---------------+---------+ | Column Name | Type | +---------------+---------+ | employee_id | int | | employee_name | varchar | | manager_id | int | +---------------+---------+ employee_id 是这个表的主键。 这个表中每一行中,employee_id 表示职工的 ID,employee_name 表示职工的名字,manager_id 表示该职工汇报工作的直线经理。 这个公司 CEO 是 employee_id = 1 的人。 用 SQL 查询出所有直接或间接向公司 CEO 汇报工作的职工的 employee_id 。 由于公司规模较小,经理之间的间接关系不超过 3 个经理。 可以以任何顺序返回无重复项的结果。 查询结果示例如下: Employees table: +-------------+---------------+------------+ | employee_id | employee_name | manager_id | +-------------+---------------+------------+ | 1 | Boss | 1 | | 3 | Alice | 3 | | 2 | Bob | 1 | | 4 | Daniel | 2 | | 7 | Luis | 4 | | 8 | Jhon | 3 | | 9 | Angela | 8 | | 77 | Robert | 1 | +-------------+---------------+------------+ Result table: +-------------+ | employee_id | +-------------+ | 2 | | 77 | | 4 | | 7 | +-------------+ 公司 CEO 的 employee_id 是 1. employee_id 是 2 和 77 的职员直接汇报给公司 CEO。 employee_id 是 4 的职员间接汇报给公司 CEO 4 --> 2 --> 1 。 employee_id 是 7 的职员间接汇报给公司 CEO 7 --> 4 --> 2 --> 1 。 employee_id 是 3, 8 ,9 的职员不会直接或间接的汇报给公司 CEO。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/all-people-report-to-the-given-manager
//测试数据 Create table If Not Exists Employees (employee_id int, employee_name varchar(30), manager_id int); insert into Employees (employee_id, employee_name, manager_id) values ('1', 'Boss', '1'); insert into Employees (employee_id, employee_name, manager_id) values ('3', 'Alice', '3'); insert into Employees (employee_id, employee_name, manager_id) values ('2', 'Bob', '1'); insert into Employees (employee_id, employee_name, manager_id) values ('4', 'Daniel', '2'); insert into Employees (employee_id, employee_name, manager_id) values ('7', 'Luis', '4'); insert into Employees (employee_id, employee_name, manager_id) values ('8', 'John', '3'); insert into Employees (employee_id, employee_name, manager_id) values ('9', 'Angela', '8'); insert into Employees (employee_id, employee_name, manager_id) values ('77', 'Robert', '1');
解题思路
题目要求从CEO(employee_id = 1)出发,找出直接下属,以及下属的下属,下属的下属的下属。
因为题目中已经说明公司层级不高,最高3级。那么可以通过穷举的方式来实现。
也就是说,**第一步**:找到CEO的直接下属;
**第二步**:找到下属的下属;
**第三步**:找到下属的下属的下属;
说起来比较拗口,但思路就是这样。如果层级更深,就继续向下查。
最后一步:合并上面3步找到的所有人,然后去重即可。
上面这种方法,SQL写起来比较简单。但仅仅针对层级不深的情况比较适用。
如果层级比较深,这种方法就显得非常臃肿。
显然,递归是一个比较好的方法。
在推文单挑力扣(LeetCode)SQL题:1613. 找到遗失的ID(难度:中等)中,我介绍了几种不同数据库实现递归的方法。
今天主要介绍下Oracle数据库中使用connect by实现递归的方法。
Oracle中,使用connect by实现递归的语法如下:
select * from table [start with condition] connect by [nocycle] [prior] id=parentid
其中,start with condition是用来限制取出第一层数据的条件;
id = parentid是用来从第一层数据出发,查出下一层次的数据的条件。
当prior的位置不变,后面条件为id = parentid时,表示从根节点出发,查出以下所有层级的节点;
当prior的位置不变,后面条件为parentid = id时,表示从叶子节点出发,查出以上所有层级的节点;
当然,也可以条件不变,改变prior关键字的位置,可以实现同样的效果。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select a.employee_id from employees a where a.employee_id <> 1 start with a.manager_id = 1 connect by nocycle prior a.employee_id = a.manager_id group by a.employee_id;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。