2015-11-08 37 views
-2

我知道如何導航層次結構與connect by這樣的:反向樹步行

SELECT RPAD ('*', 2 * LEVEL, '*') || ename ename, empno 
FROM scott.emp 
START WITH mgr IS NULL 
CONNECT BY PRIOR empno = mgr 

現在我想向後遍歷樹使用遞歸with條款,但我無法弄清楚如何做到這一點。

請幫助我。

+0

我不知道我知道你想要什麼,但你嘗試CONNECT BY PRIOR經理= EMPNO,並且可能改變與表達開始在適合? –

回答

0

關於遞歸WITH語法有兩個棘手的問題。

我們在第二個查詢中定義了兩個查詢,一個作爲錨點(START WITH值),一個UNION ALL查找分層結構的子元素。

另一個問題是我們不能使用LEVEL在CONNECT BY查詢中生成填充(因爲我們沒有使用CONNECT BY)。因此,我們添加了另一列,以在導航樹時保持級別的計數。請注意,我已從零開始,以便層次結構的頂部不會填充星號。

所以,這裏是你的查詢重新澆鑄爲遞歸WITH語句:

with e1 (ename, empno, lvl) 
     as (select ename 
        , empno 
        , 0 as lvl 
      from emp 
      where mgr is null 
      union all 
      select e2.ename 
        , e2.empno 
        , e1.lvl + 1 
       from emp e2, e1 
       where e2.mgr = e1.empno) 
search depth first by empno set empno_order 
select rpad ('*', 2 * e1.lvl, '*') || e1.ename ename 
     , e1.empno 
from e1 
order by empno_order 
; 

search depth first條款保證了結果集顯示給定節點的所有子顯示同級節點之前。 (search breadth first會列出所有的兄弟姐妹,然後開始在層次結構的下一級。)

現在,做一個反向樹走,我們需要開始與員工誰是不是經理。因爲我們檢查的是空值,我們需要使用NOT EXISTS而不是NOT IN。否則,查詢幾乎是一樣的;我選擇顯示MGR而不是EMPNO,但您可能更願意恢復。

with e1 (ename, mgr, lvl) 
     as (select e.ename 
        , e.mgr 
        , 0 as lvl 
      from emp e 
      where not exists (select null 
           from emp x 
           where x.mgr = e.empno) 
      union all 
      select e2.ename 
        , e2.mgr 
        , e1.lvl + 1 
       from emp e2, e1 
       where e2.empno = e1.mgr) 
search depth first by mgr set mgr_order 
select rpad ('*', 2 * e1.lvl, '*') || e1.ename ename 
     , e1.mgr 
from e1 
order by mgr_order 
; 

下面是該查詢樣本輸出:

ENAME         MGR 
------------------------------ ---------- 
ALLEN        7698 
**BLAKE        7839 
****KING 
JAMES        7698 
**BLAKE        7839 
****KING 
MARTIN        7698 
**BLAKE        7839 
****KING 
TURNER        7698 
...