oracle 中 Start with...connect by 的用法(遞歸查詢)

這幾個關鍵字是查詢遞歸數據的,造成一個樹狀結構。目前只有oracle支持,其餘數據都要結合存儲過程實現 oracle

語法: spa

   select * from some_table 遞歸

                  [where 條件1] ci

                  connect by [條件2] it

                  start with [條件3];    io

其中 connect by 與 start with 語句擺放的前後順序不影響查詢的結果,[where 條件1]能夠不須要。 table

 [where 條件1]、[條件2]、[條件3]各自做用的範圍都不相同:      test

 [where 條件1]是在根據「connect by [條件2] start with [條件3]」選擇出來的記錄中進行過濾,是針對單條記錄的過濾, 不會考慮樹的結構;     原理

 [條件2]指定構造樹的條件,以及對樹分支的過濾條件,在這裏執行的過濾會把符合條件的記錄及其下的全部子節點都過濾掉;    select

 [條件3]限定做爲搜索起始點的條件,若是是自上而下的搜索則是限定做爲根節點的條件,若是是自下而上的搜索則是限定做爲葉子節點的條件; 

 

看下面的例子

TEST 表

 EMPNO  ENAME  DPT  MAR  SAL
 0075  XU  D1  0082  3000
 0082  BAO  D1  0096  4000
 0096  ZHAO  D2  NULL  5000
 0111  MU  D2  0082  4000
 0056  ZHANG  D3  0111  3000
 0923  WANG  D3  0075  2000
 

 select* from test start with EMPNO = '0111' connect by EMPNO = prior MAR

select* from test start with EMPNO = '0111' connect by prior EMPNO = MAR

 

對prior的說明:

prior存在於[條件2]中,能夠不要,不要的時候只能查找到符合「start with [條件3]」的記錄,不會在尋找這些記錄的子節點。

要的時候有兩種寫法:connect by prior empno=mgr 或 connect by empno=prior mgr,

前一種寫法表示採用自上而下的搜索方式(先找父節點而後找子節點),

後一種寫法表示採用自下而上的搜索方式(先找葉子節點而後找父節點)。

 

 

[執行原理] :

遍歷表中的每條記錄,對比是否知足start with後的條件,若是不知足則繼續下一條, 若是知足則以該記錄爲根節點.

而後遞歸尋找該節點下的子節點, 查找條件是connect by後面指定的條件,好比上面的例子,是當前記錄的empno等於其子節點的mgr,如此循環直到遍歷完整個表的全部記錄.

        若是數據有問題,出現循環,即a是b的經理,b是c的經理,c又是a的經理,查詢會出現ORA-01436: 用戶數據中的 CONNECT BY 循環 的錯誤,可在connect by後面添加nocycle 解決這個問題。
相關文章
相關標籤/搜索