1. 程式人生 > >ORACLE 樹形遍歷查詢根節點、父節點、子節點

ORACLE 樹形遍歷查詢根節點、父節點、子節點

1、準備演示資料

建立表結構:

-- Create table

createtable Z_ORG(  cid         NUMBER,  cname       VARCHAR2(32),  parent_id   NUMBER,  create_time DATE,  org_level   NUMBER)

tablespace POWERDESK

pctfree10

initrans1

maxtrans255;

-- Add comments to the table

commentontable Z_ORG  is'機構組織簡化表';

-- Add comments to the columns

commentoncolumn Z_ORG.cid  is'主鍵ID';

commentoncolumn Z_ORG.cname  is'組織名稱';

commentoncolumn Z_ORG.parent_id  is'上級組織ID';

commentoncolumn Z_ORG.create_time  is'建立時間';

commentoncolumn Z_ORG.org_level  is'組織級別';

錄入資料:

insertinto z_org(cid,cname,parent_id,create_time,org_level) select1,'地球',0,

sysdate,1from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select2,'中國',1,sysdate,2from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select3,'上海直轄市',2,sysdate,3from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select4,'江蘇省',2,sysdate

,3from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select5,'南京市',4,sysdate,4from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select6,'蘇州市',4,sysdate,4from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select7,'無錫市',4,sysdate,4from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select8,'虹口區',3,sysdate,4from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select9,'浙江省',2,sysdate,3from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select10,'杭州市',9,sysdate,4from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select11,'寧波市',9,sysdate,4from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select12,'美國',1,sysdate,2from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select13,'加利福尼亞州',12,sysdate,3from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select14,'舊金山市',13,sysdate,4from dual;

insertinto z_org(cid,cname,parent_id,create_time,org_level) select15,'撒門市',13,sysdate,4from dual;

commit;

2、遍歷根節點

1.  select  code1 from tablename  

2.  start with code2  

3.  connect by code3  

4.  where cond3 

code2是根結點的限定語句,當然可以放寬限定條件,以取得多個根結點,實際就是多棵樹。

code3是連線條件,其中用prior表示上一條記錄,比如connect by prior id=parentid就是說上一條記錄的id是本條記錄的parent,即本記錄的父親是上一條記錄。

code4是過濾條件,用於對返回的所有記錄進行過濾。


prior和start with關鍵字是可選項:

prior運算子必須放置在連線關係的兩列中某一個的前面。對於節點間的父子關係,prior運算子在一側表示父節點,在另一側表示子節點,從而確定查詢樹結構是的順序是自頂向下還是自底向上。在連線關係中,除了可以使用列名外,還允許使用列表達式。start with子句為可選項,用來標識哪個節點作為查詢樹型結構的根節點。若該子句被省略,則表示所有滿足查詢條件的行作為根節點。

遍歷表,求得某一個節點的所有上級節點記錄,比如求得撒門市的上級組織,應該獲得加利福尼亞州,美國,地球這些記錄,如下所示:

SQL>     select t.cid, t.cname, t.parent_id,level

2from z_org t

3startwith t.cname='撒門市'

4connectbynocycleprior t.parent_id=t.cid

5orderbylevelasc

6  ;

       CID CNAME                             PARENT_ID      LEVEL

---------- -------------------------------- ---------- ----------

15撒門市131

13加利福尼亞州122

12美國13

1地球04

SQL>

遍歷求得根路徑字串:

SQL>   select cname_child, wm_concat(t2.cname)

2from(

3select'蘇州市' cname_child, t.cid, t.cname, t.parent_id,level

4from z_org t

5startwith t.cname in('蘇州市')

6connectbynocycleprior t.parent_id=t.cid

7    )t2 groupby cname_child ;

CNAME_CHILD WM_CONCAT(T2.CNAME)

----------- --------------------------------------------------------------------------------

蘇州市蘇州市,地球,中國,江蘇省

SQL>

3、遍歷子節點

5.  select  code1 from tablename  

6.  start with code2  

7.  connect by code3  

8.  where cond3 

code2是根結點的限定語句,當然可以放寬限定條件,以取得多個根結點,實際就是多棵樹。

code3是連線條件,其中用prior表示上一條記錄,比如connect by prior id=parentid就是說上一條記錄的id是本條記錄的parent,即本記錄的父親是上一條記錄。

code4是過濾條件,用於對返回的所有記錄進行過濾。


prior和start with關鍵字是可選項:

prior運算子必須放置在連線關係的兩列中某一個的前面。對於節點間的父子關係,prior運算子在一側表示父節點,在另一側表示子節點,從而確定查詢樹結構是的順序是自頂向下還是自底向上。在連線關係中,除了可以使用列名外,還允許使用列表達式。
start with子句為可選項,用來標識哪個節點作為查詢樹型結構的根節點。若該子句被省略,則表示所有滿足查詢條件的行作為根節點。

如下所示,prior偏向父節點,就往下查詢,查詢節點下面所有的子節點記錄:

select t1.parent_id, t1.cid, casewhenlevel=1then'*'||t1.cname whenlevel=2then'*-----'||t1.cname whenlevel=3then'*-----*-----'||t1.cname else t1.cname end , level

from z_org t1

startwith t1.parent_id = 1

connectby  t1.cid=prior t1.parent_id

;

如下所示E:\u\oracle\problem\pic\52.png:

如下所示,prior偏向子節點,就往下查詢,查詢節點下面所有的子節點記錄:

select t1.parent_id, t1.cid, casewhenlevel=1then'*'||t1.cname whenlevel=2then'*-----'||t1.cname whenlevel=3then'*-----*-----'||t1.cname else t1.cname end , level

from z_org t1

startwith t1.parent_id = 1

connectbyprior t1.cid=t1.parent_id

;

執行結果如下所示E:\u\oracle\problem\pic\51.png:

 

4、擴充套件研究

---parentidcid開始遞迴,並以parentid為主展示這條記錄
select t1.parentid, t1.cid, level

from test_category t1
start with t1.parentid = 1
connect by prior t1.parentid = t1.cid
;
---從parentid到cid開始遞迴,並以parentid為主展示這條記錄
select t1.parentid, t1.cid, level

from test_category t1
start with t1.cid = 1
connect by prior t1.parentid = t1.cid
;

---從parentid到cid開始遞迴,並以cid為主展示這條記錄
select t1.cid, t1.parentid, level

from test_category t1
start with t1.parentid = 1
connect by t1.parentid = prior t1.cid
;
---從parentid到cid開始遞迴,並以cid為主展示這條記錄
select t1.cid, t1.parentid, level

from test_category t1
start with t1.cid = 1
connect by t1.parentid = prior t1.cid
;