将列作为级别转换为树层次结构

时间:2014-10-10 07:08:12

标签: sql oracle

我有一个如图所示的表格,想要从中创建一个树形层次结构。

enter image description here

尝试使用oracle sql执行此操作。

3 个答案:

答案 0 :(得分:0)

我建议你改变你的表结构:

emp_id          emp_name          emp_emp_id (boss of emp_id)
1                    BigBoss          NULL
2                    Boss             1
3                    Emp1             2
4                    Emp2             2

您可以通过Oracle KeyWord轻松使用连接来恢复层次结构树。 Doc Here => http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm

答案 1 :(得分:0)

让我们以SCOTT.EMP表为例创建层次结构。

SQL> SELECT empno,
  2    level,
  3    Lpad(ename,LENGTH(ename) + LEVEL * 10 - 10,'-') tree,
  4    job,
  5    mgr
  6  FROM emp
  7    START WITH mgr        IS NULL
  8    CONNECT BY PRIOR empno = mgr
  9  /

     EMPNO      LEVEL TREE                                JOB              MGR
---------- ---------- ----------------------------------- --------- ----------
      7839          1 KING                                PRESIDENT
      7566          2 ----------JONES                     MANAGER         7839
      7788          3 --------------------SCOTT           ANALYST         7566
      7876          4 ------------------------------ADAMS CLERK           7788
      7902          3 --------------------FORD            ANALYST         7566
      7369          4 ------------------------------SMITH CLERK           7902
      7698          2 ----------BLAKE                     MANAGER         7839
      7499          3 --------------------ALLEN           SALESMAN        7698
      7521          3 --------------------WARD            SALESMAN        7698
      7654          3 --------------------MARTIN          SALESMAN        7698
      7844          3 --------------------TURNER          SALESMAN        7698
      7900          3 --------------------JAMES           CLERK           7698
      7782          2 ----------CLARK                     MANAGER         7839
      7934          3 --------------------MILLER          CLERK           7782

14 rows selected.

SQL>

要理解三件重要事项,START WITHCONNECT BY PRIORLEVEL

START WITH - 指定层次结构的根。确定从哪里开始解析。

先前连接 - 这解释了父母和孩子之间的关系。先前连接empno = mgr意味着我们正在从top to bottom穿越。反转它意味着bottom to top

LEVEL - 它就像一个伪列,显示层次结构中特定行的级别或等级。

答案 2 :(得分:0)

您需要具有父子层次结构才能执行该操作。我使用HR默认架构来执行此查询:

with t(val, lvl) as (
select sys_connect_by_path(employee_id, '/'), level lvl
  from employees
 start with manager_id is null
connect by manager_id = prior employee_id
), t_corr(bigboss, boss, employee) as (
select case 
         when lvl > 1 then
           substr(val, instr(val, '/', 1, 1) + 1, instr(val, '/', 1, 2) - 1 - instr(val, '/', 1, 1)) 
         else
           substr(val, instr(val, '/', 1, 1) + 1)
       end bigboss
     , case 
         when lvl = 1 then null
         when lvl = 2 then
           substr(val, instr(val, '/', 1, 2) + 1)
         else
       substr(val, instr(val, '/', 1, 2) + 1, instr(val, '/', 1, 3) - 1 - instr(val, '/', 1, 2))
       end boss
     , case
     when lvl in (1, 2) then null
         else substr(val, instr(val, '/', 1, 3) + 1) 
       end employee
  from t
 where lvl < 4
)
select e1.last_name || ' ' || e1.first_name bigboss
     , e2.last_name || ' ' || e2.first_name boss
     , e3.last_name || ' ' || e3.first_name employee
  from t_corr
     , employees e1
     , employees e2
     , employees e3
 where t_corr.bigboss = e1.employee_id(+)
   and t_corr.boss = e2.employee_id(+)
   and t_corr.employee = e3.employee_id(+)
/

BIGBOSS              BOSS                 EMPLOYEE
-------------------- -------------------- --------------------
King Steven
King Steven          Kochhar Neena
King Steven          Kochhar Neena        Greenberg Nancy
King Steven          Kochhar Neena        Whalen Jennifer
King Steven          Kochhar Neena        Higgins Shelley
King Steven          De Haan Lex
King Steven          De Haan Lex          Hunold Alexander
King Steven          Raphaely Den
...
King Steven          Fripp Adam           Atkinson Mozhe
King Steven          Fripp Adam           Marlow James
King Steven          Fripp Adam           Olson TJ

29 rows selected.

如果您想从表中创建层次结构:

with t(a, b, c, d, e) as (
  select 'a', 'b', 'c', 'd', 'e1' from dual union all
  select 'a', 'b', 'c', 'd', 'e2' from dual union all
  select 'a', 'b', 'c', 'd', 'e3' from dual union all
  select 'a', 'b', 'c', 'd', 'e4' from dual union all
  select 'a', 'b', 'c', 'd', 'e5' from dual union all
  select 'a', 'b', 'c', 'd', 'e6' from dual union all
  select 'a', 'b', 'c', 'd', 'e7' from dual union all
  select 'a', 'b', 'c', 'd', 'e8' from dual
), tt (a, b, c, d, e) as (
  select a, lpad(b, 4, '-'), lpad(c, 8, '-'), lpad(d, 12, '-'), lpad(e, 16, '-') from t
)
select unique dd 
  from tt
unpivot(
  dd for col1 in (a, b, c, d, e)
)
order by 1 

DD
--------------------
a
---b
-------c
-----------d
--------------e1
--------------e2
--------------e3
--------------e4
--------------e5
--------------e6
--------------e7
--------------e8