题目描述

(通过次数23,521 | 提交次数35,909,通过率65.50%)

表:Employee
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
| department  | varchar |
| managerId   | int     |
+-------------+---------+
Id是该表的主键列。
该表的每一行都表示雇员的名字、他们的部门和他们的经理的id。
如果managerId为空,则该员工没有经理。
没有员工会成为自己的管理者。

编写一个SQL查询,查询至少有5名直接下属的经理 。
以 任意顺序 返回结果表。

查询结果格式如下所示。
示例 1:
输入: 
Employee 表:
+-----+-------+------------+-----------+
| id  | name  | department | managerId |
+-----+-------+------------+-----------+
| 101 | John  | A          | None      |
| 102 | Dan   | A          | 101       |
| 103 | James | A          | 101       |
| 104 | Amy   | A          | 101       |
| 105 | Anne  | A          | 101       |
| 106 | Ron   | B          | 101       |
+-----+-------+------------+-----------+
输出: 
+------+
| name |
+------+
| John |
+------+

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/managers-with-at-least-5-direct-reports
//测试数据
Create table If Not Exists Employee (id int, name varchar(255), department varchar(255), managerId int);

insert into Employee (id, name, department, managerId) values ('101', 'John', 'A', 'None');
insert into Employee (id, name, department, managerId) values ('102', 'Dan', 'A', '101');
insert into Employee (id, name, department, managerId) values ('103', 'James', 'A', '101');
insert into Employee (id, name, department, managerId) values ('104', 'Amy', 'A', '101');
insert into Employee (id, name, department, managerId) values ('105', 'Anne', 'A', '101');
insert into Employee (id, name, department, managerId) values ('106', 'Ron', 'B', '101');

解题思路

题目给出的源表,主键为雇员ID。一个雇员一条记录。managerId为雇员的直接上级经理。

实际上,经理也是雇员中的一个。所以,可以通过manageId与表中的ID字段关联,获取到经理的姓名。

根据题目要求,需要返回有5名及以上下属的经理,并返回经理姓名。

那么,我们需要以下两个步骤,来得到最终结果:

**第一步**:计算出有5个及以上直接下属的经理ID;

这是一个典型的分组统计,并根据聚合的值再过滤的场景。可以使用GROUP BY + HAVING来实现。

**第二步**:根据第一步计算出的经理ID,关联出经理的姓名;

这一步比较简单,直接使用关联,或者子查询就可以。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select
    b.name
from (
		select
		        a.managerId
		from Employee a
		group by a.managerId
		having count(1)>=5
)a
inner join Employee b
on a.managerId = b.id;
picture loss