2016-09-24 3 views
1

У меня есть таблица, в которой есть строки в родительских дочерних отношениях. Максимальная глубина отношений между родителями и детьми равна 3.Отдельные столбцы с использованием connect by

У одного родителя будет только один ребенок.

определения таблицы -

CREATE TABLE USERS { 
    empid NUMBER, 
    name VARCHAR2, 
    department VARCHAR2(20), 
    oldempid NUMBER, 
} 

данных -

EMPID NAME DEPARTMENT OLDEMPID 
    1 FOO   IT  2 
    2 null   HR  4 
    3 BAR  ADMIN  null 
    4 null  DESIGN  null 

Желаемая выход -

EMPID NAME DEPARTMENT_1 DEPARTMENT_2 DEPARTMENT_3 
    1 FOO   IT   HR  DESIGN 
    3 BAR  ADMIN   null   null 

Полный Желаемая выход -

EMPID NAME DEPARTMENT_1 DEPARTMENT_2 DEPARTMENT_3 OLDEMPID_1 OLDEMPID_2 
    1 FOO   IT   HR  DESIGN   2   4 
    3 BAR  ADMIN   null   null  null  null 

Я попытался с помощью CONNECT BY PRIOR

SELECT CONNECT_BY_ROOT EMPID, 
     NAME, 
     RTRIM(LTRIM(SYS_CONNECT_BY_PATH(DEPARTMENT, '-'), '-'), '-') AS DEPARTMENT, 
     RTRIM(LTRIM(SYS_CONNECT_BY_PATH(OLDEMPID, '-'), '-'), '-') AS OLDEMPID 
    FROM USERS 
    WHERE CONNECT_BY_ISLEAF = 1 
    CONNECT BY PRIOR OLDEMPID = EMPID; 

Выход я получаю -

EMPID NAME DEPARTMENT  OLDEMPID 
    1 null IT-HR-DESIGN 1-2-4 
    3 BAR ADMIN    null 

ответ

2

Вы также должны поворачивать свои результаты. Вы можете сделать это вручную, или вы можете использовать операцию PIVOT (поскольку вы отметили это с помощью oracle11g - первой версии, в которой PIVOT стал доступен). Подзапрос (в предложении FROM в конце) представляет собой иерархический запрос с «connect by».

with 
    users (EMPID, NAME, DEPARTMENT, OLDEMPID) as (
     select 1, 'FOO', 'IT' , 2 from dual union all 
     select 2, null , 'HR' , 4 from dual union all 
     select 3, 'BAR', 'ADMIN' , null from dual union all 
     select 4, null, 'DESIGN', null from dual 
    ), 
    tops (empid) as ( 
     select empid from users minus 
     select oldempid from users 
    ) 
select cbr_empid as empid, cbr_name as name, 
     "1_DEPARTMENT" as department_1, "2_DEPARTMENT" as department_2, 
     "3_DEPARTMENT" as department_3, "2_EMPID" as oldempid_2, "3_EMPID" as oldempid_3 
from (
     select empid, department, level as lvl, 
       connect_by_root(empid) as cbr_empid, connect_by_root(name) as cbr_name 
     from users 
     connect by prior oldempid = empid 
     start with empid in (select empid from tops) 
    ) 
pivot (max(department) as department, max(empid) as empid for lvl in (1, 2, 3)) 
; 

ВЫВОД:

 EMPID NAME DEPARTMENT_1 DEPARTMENT_2 DEPARTMENT_3 OLDEMPID_2 OLDEMPID_3 
---------- ---- ------------ ------------ ------------ ---------- ---------- 
     1 FOO IT   HR   DESIGN    2   4 
     3 BAR ADMIN          
+0

Спасибо. Тем не менее, я все еще получаю вопрос о названии сотрудника. Я отредактировал вопрос. Можете ли вы, пожалуйста, посмотреть? – JHS

+0

Вы делаете с «именем» именно то, что я сделал с «empid». Я обновил ответ, чтобы включить NAME. – mathguy