2014-10-10 110 views

回答

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 
+0

我知道如何创建一个层次,但在我的表第一列包含顶级节点,第二个包含两个级别的节点等等...我有五列,并想创建一个5级的树。请参阅此链接 - (http://imgur.com/OrvKgCU) – 2014-10-10 09:30:18

+0

查看我更新的帖子 – zaratustra 2014-10-10 09:57:02

0

我建议你改变你的表结构是这样的:

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

的,你可以easyly使用Oracle关键字连接到恢复层次树。 Doc Here =>http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm

+0

我知道如何创建一个层次结构,但在我的表中,第一列包含顶层节点,第二层包含第二层的节点,等等......我有五列,并且想要创建一个5层的树。请参考此链接 - (http://imgur.com/OrvKgCU) – 2014-10-10 09:28:35

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 - 指定层次的根。确定从哪里开始解析。

CONNECT BY PRIOR - 这解释了父母与孩子之间的关系。以前连接empno = mgr表示我们正在穿越top to bottom。反转意味着bottom to top

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

+0

我没有任何父母子女关系在我的表中。我如何创建一个 – 2014-10-10 08:36:06

+0

您有权访问SCOTT模式吗?如果你看员工表,你会明白什么是必需的。 – 2014-10-10 08:38:49

+0

我知道如何创建一个层次结构,但在我的表中,第一列包含顶层节点,第二层包含第二层的节点,等等......我有五列,并且想要创建一个具有5个层次的树。 – 2014-10-10 08:53:59