Вот, пожалуйста !!
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) Мы должны повторять вышеупомянутые шаги, пока не останется больше Менеджеров для Менеджеров. Теперь мы знаем, что нет менеджера для 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
Наконец, если мы объединим ( union ) все значения из всех этих запросов, мы получим требуемые Таблица результатов . Все это делается нашим RECURSIVE CTE
в одном запросе. Здесь QueryE1
является Якорным Запросом. QueryE2,QueryE3 & QueryE4
являются рекурсивными членами, и они создаются нашим CTE, пока мы не получим 0 строк. После создания Resultant Table мы можем использовать его для настройки наших потребностей. Здесь мы делаем Group by
, чтобы получить count
ManagerID. Я не уверен, удалит ли это ваше замешательство, но, по крайней мере, надеюсь, что вы поймете:)