2
create table employee (
Id int,
ManagerId int);

insert into employee values
(1, 3),
(2, 3),
(3, 6),
(4, 7),
(5, 7),
(6, 8),
(7, 6);

select * from employee;

这是表格:

在此处输入图像描述

如何编写查询以获取拥有员工人数的经理。注意嵌套结构。上面例子的结果是

Id | number_of_employees
3  | 2
7  | 2
6  | 6
8  | 7
4

1 回答 1

2

干得好!!

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 byManagerID。那么我们将如何实现这一目标。

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的是获取countManagerID。我不确定它是否会消除您的困惑,但至少希望您能有所了解:)

于 2019-11-12T06:09:08.800 回答