1. 程式人生 > 其它 >Oracle遞迴查詢父子兄弟節點

Oracle遞迴查詢父子兄弟節點

1、查詢某節點下所有後代節點(包括各級父節點)

1 // 查詢id為101的所有後代節點,包含101在內的各級父節點
2 select t.* from SYS_ORG t start with id = '101' connect by parent_id = prior id

2、查詢某節點下所有後代節點(不包含各級父節點)

1 select t.*
2   from SYS_ORG t
3  where not exists (select 1 from SYS_ORG s where s.parent_id = t.id)
4  start with id = '101'
5 connect by parent_id = prior id

3、查詢某節點所有父節點(所有祖宗節點) 

1 select t.*
2   from SYS_ORG t
3  start with id = '401000501'
4 connect by prior parent_id = id

4、查詢某節點所有的兄弟節點(親兄弟)

1 select * from SYS_ORG t
2 where exists (select * from SYS_ORG s where t.parent_id=s.parent_id and s.id='401000501')

5、查詢某節點所有同級節點(族節點),假設不設定級別欄位

1 with tmp as(
2       select t.*, level leaf        
3       from SYS_ORG t               
4       start with t.parent_id = '0'     
5       connect by t.parent_id = prior t.id)
6 select *                               
7       from tmp                             
8 where leaf = (select leaf from tmp where id = '401000501');

這裡使用兩個技巧,一個是使用了level來標識每個節點在表中的級別,還有就是使用with語法模擬出了一張帶有級別的臨時表

 6、查詢某節點的父節點及兄弟節點(叔伯節點)

with tmp as(
    select t.*, level lev
    from SYS_ORG t
    start with t.parent_id = '0'
    connect by t.parent_id = prior t.id)  
select b.*
from tmp b,(select *
            from tmp
            where id = '401000501' and lev = '2') a
where b.lev = '1'
 
union all
 
select *
from tmp
where parent_id = (select distinct x.id
                from tmp x, --祖父
                     tmp y, --父親
                     (select *
                      from tmp
                      where id = '401000501' and lev > '2') z --兒子
                where y.id = z.parent_id and x.id = y.parent_id); 

這裡查詢分成以下幾步。
首先,將全表都使用臨時表加上級別;
其次,根據級別來判斷有幾種型別,以上文中舉的例子來說,有三種情況:
(1)當前節點為頂級節點,即查詢出來的lev值為1,那麼它沒有上級節點,不予考慮。
(2)當前節點為2級節點,查詢出來的lev值為2,那麼就只要保證lev級別為1的就是其上級節點的兄弟節點。
(3)其它情況就是3以及以上級別,那麼就要選查詢出來其上級的上級節點(祖父),再來判斷祖父的下級節點都是屬於該節點的上級節點的兄弟節點。
最後,就是使用union將查詢出來的結果進行結合起來,形成結果集。

 

1、查詢某節點下所有後代節點(包括各級父節點)

1 // 查詢id為101的所有後代節點,包含101在內的各級父節點
2 select t.* from SYS_ORG t start with id = '101' connect by parent_id = prior id

2、查詢某節點下所有後代節點(不包含各級父節點)

1 select t.*
2   from SYS_ORG t
3  where not exists (select 1 from SYS_ORG s where s.parent_id = t.id)
4  start with id = '101'
5 connect by parent_id = prior id

3、查詢某節點所有父節點(所有祖宗節點) 

1 select t.*
2   from SYS_ORG t
3  start with id = '401000501'
4 connect by prior parent_id = id

4、查詢某節點所有的兄弟節點(親兄弟)

1 select * from SYS_ORG t
2 where exists (select * from SYS_ORG s where t.parent_id=s.parent_id and s.id='401000501')

5、查詢某節點所有同級節點(族節點),假設不設定級別欄位

1 with tmp as(
2       select t.*, level leaf        
3       from SYS_ORG t               
4       start with t.parent_id = '0'     
5       connect by t.parent_id = prior t.id)
6 select *                               
7       from tmp                             
8 where leaf = (select leaf from tmp where id = '401000501');

這裡使用兩個技巧,一個是使用了level來標識每個節點在表中的級別,還有就是使用with語法模擬出了一張帶有級別的臨時表

 6、查詢某節點的父節點及兄弟節點(叔伯節點)

with tmp as(
    select t.*, level lev
    from SYS_ORG t
    start with t.parent_id = '0'
    connect by t.parent_id = prior t.id)  
select b.*
from tmp b,(select *
            from tmp
            where id = '401000501' and lev = '2') a
where b.lev = '1'
 
union all
 
select *
from tmp
where parent_id = (select distinct x.id
                from tmp x, --祖父
                     tmp y, --父親
                     (select *
                      from tmp
                      where id = '401000501' and lev > '2') z --兒子
                where y.id = z.parent_id and x.id = y.parent_id); 

這裡查詢分成以下幾步。
首先,將全表都使用臨時表加上級別;
其次,根據級別來判斷有幾種型別,以上文中舉的例子來說,有三種情況:
(1)當前節點為頂級節點,即查詢出來的lev值為1,那麼它沒有上級節點,不予考慮。
(2)當前節點為2級節點,查詢出來的lev值為2,那麼就只要保證lev級別為1的就是其上級節點的兄弟節點。
(3)其它情況就是3以及以上級別,那麼就要選查詢出來其上級的上級節點(祖父),再來判斷祖父的下級節點都是屬於該節點的上級節點的兄弟節點。
最後,就是使用union將查詢出來的結果進行結合起來,形成結果集。

      轉自:https://www.cnblogs.com/dahaihh-2018/p/8274617.html