2009-05-21 38 views
2

我有一個分層查詢來跟蹤報告結構。這幾乎可以工作,除非它沒有報告頂級節點,可能是因爲頂級人員「自我報告」。Oracle分層查詢:如何包含頂層父項

查詢是:

select 
    level, 
    empid, 
    parentid 
from usertable 
connect by nocycle prior parentid= empid 
start with empid = 50 

這將產生:

LEVEL EMPID PARENTID    
------ ----- -------- 
1  50 258    
2  258 9555 
3  9555 17839 

我沒有得到一個4級,因爲它看起來像:

4  17839 17839 

不改變數據,有沒有辦法修改我的查詢,以便返回所有4個級別?我們的目標是讓empids,這樣我就可以爲

id in (hierarchical subquery)

做一次檢查順便說一句,如果我從查詢中刪除我得到一個錯誤的NOCYCLE。

回答

5

克里斯,

你只得到3行,因爲你的頂層行不設置應該的方式來處理層次查詢。通常情況下,頂級行或Oracle着名的EMP表中的總裁KING都沒有經理。在你的情況下,你不應該把17389的參數設置爲17389本身,而是設置爲NULL。要麼相應地更新表格,要麼使用視圖來適應這種情況。

一個例子:

SQL> select empno 
    2  , mgr 
    3 from emp 
    4 where empno in (7876,7788,7566,7839) 
    5/

    EMPNO  MGR 
---------- ---------- 
     7566  7839 
     7788  7566 
     7839  7839 
     7876  7788 

4 rijen zijn geselecteerd. 

EMP表的這一部分有四個級別設置爲自身其頂部水平行(7839)。與您的EMPID 17839.這使用您的查詢導致只有三行:

SQL> select level 
    2  , empno 
    3  , mgr 
    4  from emp 
    5 connect by nocycle prior mgr = empno 
    6 start with empno = 7876 
    7/

    LEVEL  EMPNO  MGR 
---------- ---------- ---------- 
     1  7876  7788 
     2  7788  7566 
     3  7566  7839 

3 rijen zijn geselecteerd. 

要麼使用一個(內聯)視圖設置經理/ parentId的列設置爲空的頂級:

SQL> select level 
    2  , empno 
    3  , mgr 
    4  from (select empno 
    5     , nullif(mgr,empno) mgr 
    6    from emp 
    7   ) 
    8 connect by nocycle prior mgr = empno 
    9 start with empno = 7876 
10/

    LEVEL  EMPNO  MGR 
---------- ---------- ---------- 
     1  7876  7788 
     2  7788  7566 
     3  7566  7839 
     4  7839 

4 rijen zijn geselecteerd. 

或修復您的數據UPDATE語句:

SQL> update emp 
    2  set mgr = null 
    3 where empno = 7839 
    4/

1 rij is bijgewerkt. 

SQL> select level 
    2  , empno 
    3  , mgr 
    4  from emp 
    5 connect by nocycle prior mgr = empno 
    6 start with empno = 7876 
    7/

    LEVEL  EMPNO  MGR 
---------- ---------- ---------- 
     1  7876  7788 
     2  7788  7566 
     3  7566  7839 
     4  7839 

4 rijen zijn geselecteerd. 

而且你可以離開了NOCYCLE關鍵字以及,你做固定後。

Regards, Rob。

3

您需要以相反的方式執行層次結構,從根到葉。

select 
    level, 
    empid, 
    parentid 
from usertable 
start with empid = 17839 
connect by empid != 17839 and prior empid = parentid 

LEVEL     EMPID     PARENTID    
---------------------- ---------------------- ---------------------- 
1      17839     17839     
2      9555     17839     
3      258     9555     
4      50      258      

4 rows selected 
+0

不幸的是,這不起作用。 頂層將有一大堆的2級的,但我只希望在上述水平4.思考的員工,經理,總監,副總裁層次結構中的2級 - 導演和VP可以看到員工創建的數據,但另一向該董事報告的經理不能。 – chris 2009-05-21 14:42:17

0

好像你在數據的週期。如果沒有「nocycle」,它將不會馬上起作用。如果您知道所有數據的最大嵌套級別爲4,則可以添加條件「和級別< = 4」並刪除nocycle。應該管用。

+0

不幸的是,嵌套級別會有所不同。 – chris 2009-05-21 14:43:25

1

您不必更改結構。

只需使用下面的查詢

select 
    level, 
    empid, 
    parentid 
from usertable 
connect by prior parentid = empid 
     AND parentid <> empid -- This line prohibits cycling and ALLOWS a row where parentid = empid 
start with empid = 50 
0

凡Heddegem Roeland的答案不適合我的工作,我已經試過了,但我已經成功地做到這一點沒有一個內嵌視圖,在連接子句中,通過添加: -

and prior empid <> parentid 

下面的文章解釋了爲什麼這樣的作品 - 如果你可以讓你的頭轉過來!儘管一旦你「明白了」它確實是合乎邏輯的。 (這是與<>運營商的每一側的計算順序做。)

Oracle: Connect By Loop in user data

內聯視圖會工作,但不會對您的特定數據集的研究,我不知道什麼樣的影響內嵌視圖可能在查詢路徑上。在大多數情況下,添加額外的子句可能是「正確的」方法,恕我直言。