在oracle中的select語句能夠用start with...connect by prior子句實現遞歸查詢。其基本語法是:sql
select LEVEL,t.* from tablename t where cond3 start with cond1 connect by cond2;
注意:這裏的where條件是放在tablename後面,若是放在cond2後面,執行查詢報sql命令未正確結束的錯誤。oracle
cond1:是根結點的限定語句,固然能夠放寬限定條件,以取得多個根結點,實際就是多棵樹。 spa
cond2:是鏈接限定條件,格式爲「PRIOR 列名1=列名2」 或 「列名1=PRIOR 列名2」。其中用prior表示上一條記錄,好比connect by prior id=parentid就是說上一條記錄的ID是本條記錄的parentid,即本記錄的父親是上一條記錄。 code
cond3:是結果過濾條件,用於對返回的全部記錄進行過濾(即在樹查詢出來後再進行過濾)。 排序
簡單說來是將一個樹狀結構存儲在一張表裏,好比一個表中存在兩個字段: id,parent_id
那麼能夠經過該查詢表示每一條記錄的parent是誰,就能夠造成一個樹狀結構。 遞歸
一、關於start with
START WITH 子句爲可選項,用來標識哪一個節點做爲查找樹型結構的起始節點。若該子句被省略,則表示全部知足查詢條件的行做爲起始節點。不但能夠指定一個起始節點,還能夠指定多個起始節點。ci
二、 關於 PRIOR
在自頂向下查詢樹結構時,不但能夠從根節點開始,還能夠定義任何節點爲起始節點,以此開始向下查找。這樣查找的結果就是以該節點爲開始的結構樹的一枝。運算符 PRIOR 被放置於等號先後的位置,決定着查詢時的檢索順序。
PRIOR 被置於 CONNECT BY 子句中等號的前面時,則強制從根節點到葉節點的順序檢索,即由父節點向子節點方向經過樹結構,咱們稱之爲自頂向下的方式。如:
CONNECT BY PRIOR EMPNO=MGR
PIROR 運算符被置於 CONNECT BY 子句中等號的後面時,則強制從葉節點到根節點的順序檢索,即由子節點向父節點方向經過樹結構,咱們稱之爲自底向上 的方式。例如:
CONNECT BY EMPNO=PRIOR MGR
在這種方式中也應指定一個開始的節點。it
三、使用LEVEL
在具備樹結構的表中,每一行數據都是樹結構中的一個節點,因爲節點所處的層次位置不一樣,因此每行記錄均可以有一個層號。層號根據節點與根節點的距離肯定。不論從哪一個節點開始,該起始節點的層號始終爲1 ,起始節點的子節點爲2,依此類推。io
四、節點和分支的裁剪
在對樹結構進行查詢時,能夠去掉表中的某些行,也能夠剪掉樹中的一個分支,使用WHERE子句來限定樹型結構中的單個節點,以去掉樹中的單個節點,但它卻不影響其後代節點(自頂向下檢索時)或前輩節點(自底向頂檢索時)。table
五、排序顯示
像在其它查詢中同樣,在樹結構查詢中也能夠使用ORDER BY子句,改變查詢結果的顯示順序,而沒必要按照遍歷樹結構的順序。
--------------------------------------------------------------------------------
分割線
--------------------------------------------------------------------------------
上面簡單介紹了oracle樹結構查詢語法,下面說明下實際應用中,因重複數據致使的特殊狀況。
場景:一張表test_table中存儲每一個核心繫統source,且每一個source有本身專業機構id,每一個專業機構下有相應的下級機構。但各個核心間的機構id存在重複。表數據如表1所示。
表1
id | parent_id | source |
---|---|---|
201 | 1 | 核心1 |
1 | 核心1 | |
20108 | 201 | 核心1 |
20108 | 201 | 核心2 |
201 | 2 | 核心2 |
2 | 核心2 |
表2
id | parent_id | source |
---|---|---|
20108 | 201 | 核心1 |
201 | 1 | 核心1 |
1 | 核心1 | |
201 | 2 | 核心2 |
2 | 核心2 | |
20108 | 201 | 核心2 |
201 | 1 | 核心1 |
1 | 核心1 | |
201 | 2 | 核心2 |
2 | 核心2 |
表3
id | parent_id | source |
---|---|---|
20108 | 201 | 核心1 |
201 | 1 | 核心1 |
1 | 核心1 | |
201 | 1 | 核心1 |
1 | 核心1 |
實際數據爲核心1有專業機構爲id=1,二級機構爲id=201,三級機構爲id=20108;核心2有專業機構爲id=2,二級機構爲id=201,三級機構爲id=20108。
若是在不知道表內具體數據的狀況下,直接使用如下語句從三級機構id=20108遍歷查詢其根節點,結果如表2所示。致使該緣由是20108存在重複,201也存在重複,分別關聯遞歸出多個樹結構。
select * from test_table t start with t.id = '20108' connect by t.id = prior t.parent_id;
若是此時加上where條件,只查詢核心系統1的三極機構id=20108對應的機構樹結構。效果如表3所示。很明顯where條件只是在表2的基礎上進行再次篩選而已,結果不是咱們想要的三級層次樹結構。
select * from test_table t where t.source = '核心1' start with t.id = '20108' connect by t.id = prior t.parent_id;
解決因不一樣核心數據重複致使關聯出多個樹結構問題,只需將限定條件加在start with和connect by上便可。具體SQL以下,效果詳見表4。
select * from test_table t start with (t.id = '20108' and t.source = '核心1') connect by (t.id = prior t.parent_id and t.source = '核心1');
表4
id | parent_id | source |
---|---|---|
20108 | 201 | 核心1 |
201 | 1 | 核心1 |
1 | 核心1 |