Oracle遞歸函數查詢樹形結構數據-connect by ,level的使用


1.數據組成

PS:文末有insert語句,注意最后一列的列名為leval

 

2.基本查詢

2.1.查詢某節點及該節點下的所有子孫節點

SELECT   * 
     FROM QIANCODE.TREE_TABLE_BASIC T
  START WITH T.ID='111'
CONNECT BY PRIOR  T.ID=T.PID
結果如下所示:
 
注意:若prior關鍵字缺省:則只能查詢到符合條件的起始行,並不進行遞歸查詢;
SELECT  *
    FROM QIANCODE.TREE_TABLE_BASIC T
  START WITH T.ID='111'
CONNECT BY  T.ID=T.PID
結果如下所示:

2.查詢某節點及該節點上的所有祖先節點

SELECT   *
     FROM QIANCODE.TREE_TABLE_BASIC T
  START WITH T.ID='111'
CONNECT BY PRIOR T.PID=T.ID;
結果如下圖所示:

3.按層級展示某節點下的所有子節點(LEVEL的使用;注意where條件放在start with之前,order by 放最后)

/*在樹形結構節點很多的情況一下,一般會采用異步刷新的方式進行,在默認加載的情況下,會展開到某個層級。
這種情況下,不但要獲取某個節點的祖先節點,還需要獲取祖先節點的兄弟節點,在這種情況下可以通過level進行*/

SELECT   id,name,pid,leval,level 
    FROM  bianli T
 WHERE LEVEL >= 1
 START WITH T.ID = '111'
CONNECT BY PRIOR T.ID = T.PID
 ORDER BY LEVEL, ID;
顯式結果如下:
 

 

 

注意:level顯式的是偽列,是按當前查詢出來的結果進行層級排序。

          所以這里在原數據中層級為4的班主任在當前查詢中level為2.

 

 

 4.顯式出樹的級別查詢

4.1.RPAD()和LPAD()函數的使用

RPAD(string,length,[pad_string])、LPAD(string,length,[pad_string]):從左或往右使用指定的字符串pad_string對string進行填充;
                                                                                                                       pad_string可省略,默認使用空格填充;
                                                                                                                       length表示字符最終返回的總長度。

如下查詢:

select   rpad('aabbcc',2,'hh')      from   dual;    --返回 ‘aa’
select   rpad('aabbcc',12,'hh')    from   dual;    --返回 ‘aabbcchhhhhh’

4.2.區別函數lengthb(string)和length(string)

lengthb(string):計算string所占的字節長度:返回字符串的長度,單位是字節。
length(string):計算string所占的字符長度:返回字符串的長度,單位是字符。
 
如下查詢:
SELECT LENGTHB('中國') FROM DUAL;   -- 返回 6
SELECT LENGTH('中國') FROM DUAL;     -- 返回 2
對於單字節字符,LENGTHB和LENGTH是一樣的.可以用length(‘string’)=lengthb(‘string’)判斷字符串是否含有中文。
注:一個漢字在Oracle數據庫里占多少字節跟數據庫的字符集有關,UTF8時,長度為三。

 

select t.id,LENGTHB(name),4*(leval-1),Lpad(t.name,LENGTHB(name)+4*(leval-1)),
Lpad(t.name,leval*7),RPAD('  ',4*(leval-1))||name,
t.pid,t.leval from BIANLI t START WITH pID='-99999' CONNECT BY PRIOR ID=PID

上面的語句RPAD('  ',4*(leval-1))中注意是'   '而不是'' 

 

4.3.巧妙利用函數RPAD(),展示更整齊

 從上面的效果看最后第三列的顯示更好看

5.其他常用

SELECT   T.ID
                ,T.NAME
                ,T.PID
                ,CONNECT_BY_ISLEAF                                LEAF               -- 判斷是否為葉結點,O否1是
                ,SYS_CONNECT_BY_PATH(T.NAME,'|')       PATH              -- 遍歷的路徑
                ,CONNECT_BY_ROOT(T.NAME)                   ROOT             -- 遍歷根結點         
                 --,CONNECT_BY_ISCYCLE                          ISCYCLE         -- 查詢樹是否有環路【使用connect_by_iscycle時,必須加上nocycle關鍵字】
                 ,level                                                               LEVELS           -- 結點所屬樹的層數
       FROM QIANCODE.TREE_TABLE_BASIC T
 START WITH T.ID='1'
CONNECT BY PRIOR T.ID=T.PID;
 
查詢結果如下:
 
特別說明:connect_by_iscycle:偽列,驗證這個數是否有環
                  適用情景:驗證配置樹是否有環,並查出是哪個結點
                 1.修改表數據,使得表數據出現環路
                    update QIANCODE.TREE_TABLE_BASIC T set t.pid='11111' where t.id='1';commit;
                  2.再執行以上connect_by_root()查詢語句報錯   ——>   ora-01436:“用戶數據中的connect by 循環”
出現環路時問題解決如下:
                3.1.檢查是哪個結點出現問題【使用connect_by_iscycle時,必須加上nocycle關鍵字】
                    SELECT    t.id
                                     ,t.name
                                     ,t.pid,connect_by_iscycle
                         FROM QIANCODE.TREE_TABLE_BASIC T
                       START WITH T.ID='1'
                   CONNECT BY nocycle PRIOR t.id=t.pid;
                   查詢結果如下:(向下查出id=‘1111’的節點出現環路)
                   
                3.2.根據上面查出的節點id,向上遍歷找到問題結點
                   SELECT     t.id
                                     ,t.name
                                     ,t.pid,connect_by_iscycle
                        FROM QIANCODE.TREE_TABLE_BASIC T
                      START WITH T.ID='11111'
                   CONNECT BY nocycle PRIOR t.pid=t.id;
                    查詢結果如下:
                                   即可得出環路出現在id=‘1’和id=‘1111’首尾兩個節點
             4.恢復數據
                update QIANCODE.TREE_TABLE_BASIC T set t.pid='-99999' where t.id='1';commit;
 
原文:https://www.cnblogs.com/zhoudaqianhaha/p/9776619.html
 

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1', '校長', '-99999', '1');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11', '副校長1', '1', '2');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('111', '-年級教導主任', '11', '3');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1111', '一班班主任', '111', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11111', '一班語文老師', '1111', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11112', '一班數學老師', '1111', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1112', '二班班主任', '111', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11113', '二班語文老師', '1112', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11114', '二班數學老師', '1112', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('112', '二年級教導主任', '11', '3');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1113', '三班班主任', '112', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11115', '三班語文老師', '1113', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11116', '三班數學老師', '1113', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1114', '四班班主任', '112', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11117', '四班語文老師', '1114', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11118', '四班數學老師', '1114', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('12', '副校長2', '1', '2');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('113', '三年級教導主任', '12', '3');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1115', '五班班主任', '113', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11119', '五班語文老師', '1115', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11120', '五班數學老師', '1115', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1116', '六班班主任', '113', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11121', '六班語文老師', '1116', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11122', '六班數學老師', '1116', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('114', '四年級教導主任', '12', '3');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1117', '七班班主任', '114', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11123', '七班語文老師', '1117', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11124', '七班數學老師', '1117', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('1118', '八班班主任', '114', '4');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11125', '八班語文老師', '1118', '5');

insert into BIANLI (ID, NAME, PID, LEVAL)
values ('11126', '八班數學老師', '1118', '5');

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM