Можно ли использовать Oracle для получения сводного количества сотрудников на каждом уровне? - PullRequest
1 голос
/ 09 февраля 2012

Предположим, у вас есть стандартная таблица иерархии организаций в Oracle.Для простоты предположим, что в этой таблице Org есть столбец, который показывает, сколько сотрудников НАПРАВЛЕНО этой организации.

create table org (
    org_id NUMBER(5),
    parent_org_id NUMBER(5),
    emp_count NUMBER (5)
);

insert into org values (1, NULL, 200);
insert into org values (2, 1, 50);
insert into org values (3, 1, 100);
insert into org values (4, 2, 100);

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

OrgID, Count
1, 450
2, 150
3, 100
4, 100

То есть не 450 человек, НАПРАВЛЕННО назначенных на OrgId1, но когда вы добавляете всехв OrgID1 и НИЖЕ, прямо или косвенно назначено 350 человек.Опять же, с OrgId2, есть 50 назначенных непосредственно + 100 назначенных под ним (в Org 4).

Простая идея, верно?Возможен ли такой запрос в Oracle?

Ответы [ 3 ]

3 голосов
/ 20 марта 2012

Это можно сделать с помощью иерархического запроса «неправильным» способом - без условия start with означает, что каждая строка является начальной точкой, затем обходит дерево до каждого листа и группирует результаты по каждой начальной точке:

select org_id, sum(emp_count) as emp_count
from ( select connect_by_root(org_id) as org_id, emp_count
       from org 
       connect by parent_org_id=(prior org_id) )
group by org_id;

/*
ORG_ID                 EMP_COUNT             
---------------------- ----------------------
1                      450                  
2                      150                  
4                      100                  
3                      100                  
*/
0 голосов
/ 09 февраля 2012

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

create table org (
    org_id NUMBER(5),
    parent_org_id NUMBER(5),
    emp_count NUMBER (5)
);

insert into org values (1, NULL, 200);
insert into org values (2, 1, 50);
insert into org values (3, 1, 100);

select
    root_org_id,
    org_id,
    sum(emp_count)
from (
    select
        CONNECT_BY_ROOT org_id as root_org_id,
        org_id,
        emp_count
    from
        org
    start with
        parent_org_id is null
    connect by
        parent_org_id = prior org_id
)
group by rollup (root_org_id, org_id);

Это производит:

ROOT_ORG_ID,ORG_ID,SUM(EMP_COUNT)
1,1,200
1,2,50
1,3,100
1,,350
,,350

Строка с нулевым значением org_id была бы сводной записью для корневой организации. Последняя строка с пустыми значениями root_org_id и org_id - это общая сумма.

0 голосов
/ 09 февраля 2012

У меня нет оракула для проверки, но вы можете сделать что-то вроде следующего:

select OrgID
     , count(*) + (select count(*) from org orgSub where org.orgID = orgSub.parentOrgId) total
  from org
group by OrgID
...