Как найти общее количество дел по менеджерам - PullRequest
0 голосов
/ 18 июня 2020

У меня есть две таблицы: в одной есть дела вместе с сотрудниками, которые их разрешают, и в другой есть информация о сотрудниках, включая их руководителей. Я хочу сделать запрос, который находит количество дел по каждому менеджеру. В настоящее время мой запрос выглядит так

select m.id, COUNT(distinct case when e.manager_id = m.id and a.resolver_id = e.id then a.ticket_id ELSE NULL END)
from tickets a 
left join employee_info e on a.resolver_id= e.id
join employee_info m on e.manager_id = m.id
group by m.id

Этот запрос дал мне только количество непосредственных сотрудников менеджера, но не количество всех сотрудников (включая тех, кто подчиняется непосредственно руководителю). Как мне настроить свой запрос, чтобы включить в него всех сотрудников одного человека?

EDIT

Итак, это запутанный пример того, как выглядят мои таблицы

Ticket_id resolver_id
0001      11
0002      11
0003      13
0004      13
0005      12
0006      19
Id manager_id
11 01
12 01
13 11
19 12

и так я хочу, чтобы мой результат выглядел

Id count
01 6
11 4
12 2
13 2
19 1

1 Ответ

2 голосов
/ 19 июня 2020

По сути, у вас есть «дерево» сотрудников, и вы хотите рекурсивно пройти по нему. Вот для чего нужны рекурсивные CTE.

Мы определим «подчиненный» CTE, который расскажет нам обо всех «подчиненных отношениях» между всеми сотрудниками, включая «многоуровневое» подчинение. Если A является менеджером B, а B - менеджером C, тогда A имеет подчиненных B и C.

Во-первых, мы начнем со всех сотрудников, которые являются их собственными подчиненными. Это нерекурсивная часть.

    SELECT id AS id1, id AS id2
    FROM employee

Затем мы «расширяем на один уровень вниз» подчиненные отношения. если B подчиняется A, все сотрудники с B в качестве менеджера также подчиняются A. id1 остается как есть, id2 становится идентификатором «нижнего» сотрудника. Это рекурсивная часть.

    SELECT s.id1, e.id
    FROM subordinate s
    JOIN employee e ON s.id2 = e.manager_id

Затем мы вставляем обе в рекурсивный CTE. Postgres будет повторять вторую часть столько раз, сколько необходимо, пока не будут добавлены новые строки. Таким образом, мы повторно обходим все дерево сотрудников.

WITH RECURSIVE subordinate AS (
    SELECT id AS id1, id AS id2
    FROM employee
UNION
    SELECT s.id1, e.id
    FROM subordinate s
    JOIN employee e ON s.id2 = e.manager_id
)
select * from subordinate order by id1, id2;

Давайте проверим результат:

 id1 | id2 
-----+-----
   1 |   1
   1 |  11
   1 |  12
   1 |  13
   1 |  19
  11 |  11
  11 |  13
  12 |  12
  12 |  19
  13 |  13
  19 |  19

Отлично! У меня все в подчинении. У 11 есть 11 и 13, а у самых младших сотрудников, таких как 13 и 19, есть только они сами.

Как только мы это сделаем, остальное легко.

Мы можем сделать еще один CTE, подсчитывая разрешенные заявки на сотрудника:

    SELECT resolver_id as id, COUNT(*) as count
    FROM tickets
    GROUP BY resolver_id

, а затем мы вставляем все в окончательный запрос. Для каждого сотрудника просуммируйте разрешенное количество всех его подчиненных.

WITH RECURSIVE subordinate AS (
    SELECT id AS id1, id AS id2
    FROM employee
UNION
    SELECT s.id1, e.id
    FROM subordinate s
    JOIN employee e ON s.id2 = e.manager_id
),
resolved as (
    SELECT resolver_id as id, COUNT(*) as count
    FROM tickets
    GROUP BY resolver_id
)
SELECT s.id1, SUM(r.count)
FROM subordinate s
JOIN resolved r ON r.id = s.id2
GROUP BY s.id1;
...