干得好!!
With recursive cte as (
select id,Managerid from employee --> Anchor Query
union all
select c.Id,e.ManagerId from cte c --> Recursive Member
join employee e on (c.ManagerId=e.Id)) --> Termination Condition
select ManagerId,count(Id) as Number_of_Employees
from cte group by ManagerId
演示
更新
好的,让我试着解释一下。
首先,我们需要生成一个表格,列出经理下的员工以及该经理的经理直到最高级别(所有组合)。它应该像下面这样吗?让我们称之为结果表
-------------------------
| Id | ManagerId |
-------------------------
| 1 | 3 |--
| 2 | 3 | |
| 3 | 6 | |
| 4 | 7 | |->From your table
| 5 | 7 | |
| 6 | 8 | |
| 7 | 6 |--
| 2 | 6 |--
| 1 | 6 | |
| 7 | 8 | |
| 3 | 8 | |
| 5 | 6 | |-> Nested structure which you meant in the question
| 4 | 6 | |
| 4 | 8 | |
| 5 | 8 | |
| 1 | 8 | |
| 2 | 8 |--
-------------------------
一旦我们实现了上表,就可以直接查询获取count
使用的group by
ManagerID。那么我们将如何实现这一目标。
1)我们可以让直接员工使用
select Id,ManagerId from employee -- let's call this as QueryE1
2)现在让我们加入同一张桌子,让一级经理和他们的员工在一起
select e1.Id,e2.ManagerId from employee e1 join employee e2 on e1.managerid = e2.id
--QueryE2
-------------------------
| Id | ManagerId |
-------------------------
| 1 | 6 |
| 2 | 6 |
| 3 | 8 |
| 7 | 8 |
| 4 | 6 |
| 5 | 6 |
-------------------------
3)然后我们应该将上表视为参考表(QueryE2),并通过与员工表连接来找出二级经理及其员工。这里因为 8 是 6 的经理,所以 6 的报告者也是 8 的报告者。
SELECT e3.id,e4.managerid
FROM (SELECT e1.id,e2.managerid
FROM employee e1 JOIN employee e2
ON e1.managerid = e2.id) e3
JOIN employee e4
ON e3.managerid = e4.id -- QueryE3
-------------------------
| Id | ManagerId |
-------------------------
| 1 | 8 |
| 2 | 8 |
| 4 | 8 |
| 5 | 8 |
-------------------------
4) 我们应该重复上述步骤,直到不再有 Managers for Managers。现在我们知道 8 没有经理。但让我们看看查询说什么。现在我们应该考虑最新的表(上图)作为参考表。
SELECT e5.id,e6.managerid
FROM (SELECT e3.id,e4.managerid
FROM (SELECT e1.id,e2.managerid
FROM employee e1
JOIN employee e2
ON e1.managerid = e2.id) e3
JOIN employee e4
ON e3.managerid = e4.id) e5
JOIN employee e6
ON e5.managerid = e6.id --QueryE4-- returns 0 rows as well
最后,如果我们结合(联合)来自所有这些查询的所有值,我们将获得所需的结果表。这整个事情是由我们RECURSIVE CTE
在一个查询中完成的。这QueryE1
是锚查询。QueryE2,QueryE3 & QueryE4
是递归成员,它们由我们的 CTE 创建,直到我们得到 0 行。创建结果表后,我们可以使用它来定制我们的需求。这里我们正在做Group by
的是获取count
ManagerID。我不确定它是否会消除您的困惑,但至少希望您能有所了解:)