Получает статистику сотрудника и менеджера из таблицы - PullRequest
1 голос
/ 03 октября 2019

У меня есть таблица, подобная следующей:

create table tblEmp(emp varchar(10), issue_no number, mgr varchar(10));

insert into tblEmp(emp, issue_no, mgr) values('abc',123, 'xyz');
insert into tblEmp(emp, issue_no, mgr) values('ijk',222, 'xyz');
insert into tblEmp(emp, issue_no, mgr) values('abc',333, 'xyz');
insert into tblEmp(emp, issue_no, mgr) values('abc',444, 'xyz');
insert into tblEmp(emp, issue_no, mgr) values('kkk',555, 'lll');
insert into tblEmp(emp, issue_no, mgr) values('kkk',555, 'lll');

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

Выходные данные должны быть такими, как

user  issue_count
-----------------
xyz       4
  abc     3
  ijk     1
lll       2
  kkk     2

Приказ работника, у которого нет репортажей, может быть в любом порядке.

Ответы [ 2 ]

0 голосов
/ 03 октября 2019

Вы можете использовать иерархический запрос, чтобы получить счет на любой глубине иерархии, используя CONNECT_BY_ROOT, чтобы получить менеджеров репортеров на каждом уровне иерархии. Для этого требуется только одно сканирование таблицы (в отличие от запросов, использующих UNION).

SELECT "USER",
       COUNT( * ) AS issue_count
FROM   (
  SELECT CONNECT_BY_ROOT( mgr ) AS mgr,
         emp
  FROM   tblEmp
  CONNECT BY PRIOR emp = mgr
)
UNPIVOT ( "USER" FOR value IN ( emp, mgr ) )
GROUP BY "USER"

Вывод :

USER | ISSUE_COUNT
:--- | ----------:
ijk  |           1
kkk  |           2
lll  |           2
abc  |           3
xyz  |           4

db <> fiddle здесь


Обновление :

Если вы хотите, чтобы он был упорядочен иерархией, товсе становится намного сложнее:

WITH issues_with_top_level_managers ( emp, issue_no, mgr ) AS (
  SELECT emp, issue_no, mgr
  FROM   tblEmp
  UNION ALL
  (
    SELECT mgr, NULL, NULL
    FROM   tblEmp
    MINUS
    SELECT emp, NULL, NULL
    FROM   tblEmp
  )
),
grouped_issues ( emp, issue_count, mgr ) AS (
  SELECT emp,
         COUNT( issue_no ) AS issue_count,
         mgr
  FROM   issues_with_top_level_managers
  GROUP BY emp, mgr
)
SELECT emp,
       ( SELECT SUM( issue_count )
         FROM   grouped_issues c
         START WITH c.emp = gi.emp
         CONNECT BY PRIOR emp = mgr ) AS issue_count
FROM   grouped_issues gi
START WITH mgr IS NULL
CONNECT BY PRIOR emp = mgr
ORDER SIBLINGS BY emp

Вывод :

EMP | ISSUE_COUNT
:-- | ----------:
lll |           2
kkk |           2
xyz |           4
abc |           3
ijk |           1

db <> Fiddle здесь

0 голосов
/ 03 октября 2019

Вы можете использовать UNION ALL. Сложная задача - правильно упорядочить записи;Вы можете установить некоторые флаги в запросе UNION ed, чтобы иметь возможность правильно упорядочить записи во внешнем запросе:

select usr, cnt from (
    select mgr usr, mgr, 1 pos, count(*) cnt from tblEmp group by mgr
    union all 
    select emp, mgr, 2, count(*) from tblEmp group by emp, mgr
)
order by mgr, pos, usr

Демонстрация на DB Fiddle :

USR | CNT
:-- | --:
lll |   2
kkk |   2
xyz |   4
abc |   3
ijk |   1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...