Oracle的Connect By用法及理解
語法:
?? ? ?SELECT?...?FROM
?? ??? ? ??[WHERE?condition]?? ??? ??? ??? ??? ? ? ? ? ??--過濾某些節點
?? ?? ? ? ?[?START?WITH?[nocycle] start_condition]? ??--定義查詢的起點, 可以使用子查詢
? ??? ? ??CONNECT?BY?[[nocycle]?PRIOR?COLUMN1?=?COLUMN2 [AND ...]]; ??--定義父子關系
? ? ? ? ? order [ sibilings ] by ...
例1:
找出101雇員, 及其全下屬/上司
select *from myempstart with employee_id = 101 connect by prior employee_id = manager_id; -- 找下屬 -- connect by employee_id = prior manager_id; --找上司prior在等號哪邊,表示哪邊是"我的"
找下屬: ?"我的"employee_id = "別人的"manager_id --> 找出我的下屬 ?(向下查詢)
找上司: employee_id?=?prior?manager_id?別人的工號 = 我的經理編號 --> 別人是我的經理 & 別人是我經理的經理 --> 我的上司們
注意,level偽列只能和connect by子句結合使用,否則Oracle會返回錯誤?ORA-01788: 此查詢塊中要求 CONNECT BY 子句
例2:
統計樹形的層數
SELECT COUNT(DISTINCT LEVEL) FROM EMPLOYEESSTART WITH MANAGER_ID IS NULL CONNECT BY PRIOR EMPLOYEE_ID = MANAGER_ID;例3:
統計樹的節點數量 ,?例如, 查詢每個級別的雇員數量
select count(level) --在統計樹種節點的數量時, 一定不能加distinct!from employeesstart with manager_id is null connect by prior employee_id = manager_idgroup by level;例4:
刪除子樹
delete from myempwhere employee_id in ( select employee_idfrom myempstart with last_name = 'Kochhar'connect by prior employee_id = manager_id)場景1:使用 where 過濾某些節點?, 注意不是過濾分支!
例1:
查看level=2的所有雇員的信息
select level, employee_id, last_name, manager_idfrom employeeswhere level = 2 --注意where子句出現的位置start with manager_id is null connect by prior employee_id = manager_id;注意:where子句比connect?by后執行。
即先用connect?by生成一顆樹, 然后再用where來砍樹, 并不是where在前面就先執行它
例2:
查詢Mavris是不是Kochhar的雇員
SELECT * FROM employees WHERE last_name = 'Mavris' START WITH last_name = 'Kochhar' --Kochhar的所有雇員 CONNECT BY PRIOR employee_id = manager_id;場景2: 使用 connect by ?... and ... 過濾某些分支
例1 查詢Raphaely及其的所有下屬?
select *from employeesstart with last_name = 'Raphaely' connect by prior employee_id = manager_id?例2 查詢除了Raphaely和他下屬的所有員
select *from employeesstart with manager_id is null connect by prior employee_id = manager_idand last_name <> 'Raphaely';格式化查詢 ?lpad('-', 3 * (level - 1), '-')
例:使用三個橫杠作為縮進格式化查詢
select *from employeesstart with manager_id is null connect by prior employee_id = manager_idand last_name <> 'Raphaely';?
?
SYS_CONNECT_BY_PATH() 函數?☆
作用:
? ? ? ? 將父節點到當前節點的路徑按照指定的模式展現出來
格式:
? ??? ??sys_connect_by_path(<列明>,<連接串>)
CONNECT_BY_ISLEAF 偽列
作用:
? ??? ??判斷層次查詢結果集中的行是不是葉子節點
返回值:
? ??? ??0表示不是葉子節點,
? ??? ??1表示是葉子節點
例:
?
?
CONNECT_BY_ROOT 字段x -> 找到該節點最頂端節點的字段x
用在列名之前,找出此行的根節點行的相同列名的值
不是一直找到"根", 而是一直找到當前便利的分支的
select last_name "Employee",connect_by_root last_name "Manager",sys_connect_by_path(last_name, ' -> ') "Path"from hr.employees where level > 1 -- start with 加不加?? connect by prior employee_id = manager_id order by last_name, length("Path");思考? 為什么不能加 start with ? ?加了會有什么效果?
不加start with , 則每個節點都遍歷一次 , connect_by_root 找到頂端的經理人會不同
而加了start with manager_id is null 則從樹的根節點 King 開始遍歷, 從而connect_by_root每個人的頂端的經理都是King
?10g新特性 采用sibilings排序
作用:
? ? ? ? 因為使用order?by排序會破壞層次,所以在oracle10g中,增加了siblings關鍵字的排序給葉子節點的關鍵字排序
語法:
????order?siblings?by?<expre>?asc|desc?;?
它會保護層次,并且在每個等級中按expre排序
注意:
????order?siblings?by?必須緊跟著connect?by
? ? 所以不能再用order?by?了
例子:
select t.employee_id,t.manager_id,t.first_name,t.salary,sys_connect_by_path(t.first_name, '->'),levelfrom hr.employees tstart with manager_id is null connect by prior employee_id = manager_idorder by salary desc;?
最后的結果是嚴格按照salary排序的,這樣把層級關系都打亂了
采用sibilings排序:
select t.employee_id,t.manager_id,t.first_name,t.salary,sys_connect_by_path(t.first_name, '->'),levelfrom hr.employees tstart with manager_id is null connect by prior employee_id = manager_idorder siblings by salary desc;??
結果的樹結構沒有被打亂,且沒層級的sibilings都是按照salary排序的。
總結
以上是生活随笔為你收集整理的Oracle的Connect By用法及理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Google Play图标上传规则调整
- 下一篇: 机器学习 | 调参 Part1