Oracle樹形結構數據--基本知識
1.數據組成

2.基本查詢
2.1.查詢某節點及該節點下的所有子孫節點
SELECT *
FROM QIANCODE.TREE_TABLE_BASIC T
START WITH T.ID='111'
CONNECT BY PRIOR T.ID=T.PID
結果如下所示:
注意:若prior關鍵字缺省:則只能查詢到符合條件的起始行,並不進行遞歸查詢;
SELECT *
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 T.ID
, T.PID
, T. NAME, LEVEL
FROM QIANCODE.TREE_TABLE_BASIC T
WHERE LEVEL >= 1
START WITH T.ID = '111'
CONNECT BY PRIOR T.ID = T.PID
ORDER BY LEVEL, ID;
FROM QIANCODE.TREE_TABLE_BASIC 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.顯式出樹的級別查詢
SELECT T.ID
,
LPAD(T.NAME,LENGTHB(T.NAME)+(LEVEL-1)*4)
,T.PID
,LEVEL
FROM QIANCODE.TREE_TABLE_BASIC T
START WITH T.PID='-99999'
CONNECT BY PRIOR T.ID=T.PID;
FROM QIANCODE.TREE_TABLE_BASIC T
START WITH T.PID='-99999'
CONNECT BY PRIOR T.ID=T.PID;
查詢結果如下圖所示:
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
SELECT LENGTH('中國') FROM DUAL; -- 返回 2
對於單字節字符,LENGTHB和LENGTH是一樣的.可以用length(‘string’)=lengthb(‘string’)判斷字符串是否含有中文。
注:一個漢字在Oracle數據庫里占多少字節跟數據庫的字符集有關,UTF8時,長度為三。
注:一個漢字在Oracle數據庫里占多少字節跟數據庫的字符集有關,UTF8時,長度為三。
4.3.巧妙利用函數RPAD(),展示更整齊
SELECT T.ID
,
RPAD(' ',(LEVEL-1)*4)||T.NAME AS name
,T.PID,LEVEL
FROM QIANCODE.TREE_TABLE_BASIC T
START WITH T.PID='-99999'
CONNECT BY PRIOR T.ID=T.PID;
FROM QIANCODE.TREE_TABLE_BASIC T
START WITH T.PID='-99999'
CONNECT BY PRIOR T.ID=T.PID;
查詢結果如下:
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 循環”
出現環路時問題解決如下:
適用情景:驗證配置樹是否有環,並查出是哪個結點
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
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;
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;
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;
-------------------------------------------========================更多內容持續更新中=====================================--------------------------------------
