Найти сводные данные, сгруппированные по иерархии управления - PullRequest
0 голосов
/ 19 апреля 2020

Есть две таблицы: 1. Приложения:

 id | cost | user_id (FK)
 34756 | 1186 | 1
 37638 | 25  | 2
 37636 | 80  |  3
 37636 | 85  |  4
 37636 | 50  |  5
 37636 | 5  |   5
 37636 | 8  |   6
 37636 | 10  |  7
Таблица пользователей:
 id | mgr_id
 1 | null --- top
 2  | 1   --- top-1
 3  | 1   --- top-1
 4  | 2   --- top-2
 5  | 2   --- top-2
 6  | 3   --- top-2
 7  | 3   --- top-2

Ожидаемый результат: один столбец с двумя пользователями иерархии топ-1, а другой столбец с суммой стоимости приложения

   id | cost
   2   | 165
   3   | 98

Мой вопрос заключается в том, чтобы узнать сумму стоимости приложений для всех пользователей, которые подчиняются иерархии топ-1, сгруппированной по пользователям топ-1 иерархии. Можно ли это сделать одним запросом?

1 Ответ

1 голос
/ 19 апреля 2020

Ключом к решению этой проблемы является рекурсивный CTE для генерации менеджеров.

Однако я считаю этот вопрос сложным. Если вы хотите, чтобы все строго ниже менеджеров второго уровня, то вы можете использовать рекурсивный CTE - генерировать менеджеров и просто выбирать менеджеров второго уровня.

Но вы также хотите добавить вернуться в значения для этих менеджеров. Я думаю, что это требует еще одного дополнительного шага.

Следующее делает то, что вы хотите:

with recursive cte as (
      select u.id,'{}'::int[] as mgrs, 1 as lev
      from users u
      where mgr_id is null
      union all
      select u.id, (mgrs || array[u.mgr_id]), lev + 1
      from cte join
           users u
           on u.mgr_id = cte.id
     )
select cte.mgrs[2], sum(t.cost) + coalesce(tm.cost, 0)
from cte join
     t
     on t.user_id = cte.id left join
     (select t.user_id, sum(cost) as cost
      from t
      group by t.user_id
     ) tm
     on cte.mgrs[2] = tm.user_id
where cardinality(mgrs) >= 2
group by mgrs[2], tm.cost;

Здесь - это db <> скрипка.

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