文章詳情頁
Oracle遞歸查詢樹形數據實例代碼
瀏覽:95日期:2023-03-12 15:25:42
目錄
- 概述
- 1、數據準備
- 2 start with connect by prior遞歸查詢
- 2.1 查詢所有子節點
- 2.2 查詢所有父節點
- 2.3 查詢指定節點的根節點
- 2.4 查詢下行政組織遞歸路徑
- 3 with遞歸查詢
- 3.1 with遞歸子類
- 3.2 遞歸父類
- 4 MySQL 遞歸查找樹形結構
- 總結
概述
實際生活有很多樹形結構的數據,比如公司分為多個部門,部門下分為多個組,組下分為多個員工;省市縣的歸屬;頁面菜單欄等等。
如果想查詢某個節點的父節點或者子節點,一般通過表自身連接完成,但如果該節點的子節點還有多層結構,就需要使用遞歸調用。但如果數據量特別大,遞歸的次數指數級上升,而且查詢數據庫的次數也指數級上升,導致程序和數據庫壓力劇增,查詢時間特別長。那數據庫有沒有遞歸查詢語句呢?答案是肯定的。
start with connect by prior 遞歸查詢
1、數據準備
create table area_test( id number(10) not null, parent_id number(10), name varchar2(255) not null);alter table area_test add (constraint district_pk primary key (id));insert into area_test (ID, PARENT_ID, NAME) values (1, null, "中國");insert into area_test (ID, PARENT_ID, NAME) values (11, 1, "河南省"); insert into area_test (ID, PARENT_ID, NAME) values (12, 1, "北京市");insert into area_test (ID, PARENT_ID, NAME) values (111, 11, "鄭州市");insert into area_test (ID, PARENT_ID, NAME) values (112, 11, "平頂山市");insert into area_test (ID, PARENT_ID, NAME) values (113, 11, "洛陽市");insert into area_test (ID, PARENT_ID, NAME) values (114, 11, "新鄉市");insert into area_test (ID, PARENT_ID, NAME) values (115, 11, "南陽市");insert into area_test (ID, PARENT_ID, NAME) values (121, 12, "朝陽區");insert into area_test (ID, PARENT_ID, NAME) values (122, 12, "昌平區");insert into area_test (ID, PARENT_ID, NAME) values (1111, 111, "二七區");insert into area_test (ID, PARENT_ID, NAME) values (1112, 111, "中原區");insert into area_test (ID, PARENT_ID, NAME) values (1113, 111, "新鄭市");insert into area_test (ID, PARENT_ID, NAME) values (1114, 111, "經開區");insert into area_test (ID, PARENT_ID, NAME) values (1115, 111, "金水區");insert into area_test (ID, PARENT_ID, NAME) values (1121, 112, "湛河區");insert into area_test (ID, PARENT_ID, NAME) values (1122, 112, "舞鋼市");insert into area_test (ID, PARENT_ID, NAME) values (1123, 112, "寶豐市");insert into area_test (ID, PARENT_ID, NAME) values (11221, 1122, "尚店鎮");
2 start with connect by prior遞歸查詢
- start with 子句:遍歷起始條件。如果要查父結點,這里可以用子結點的列,反之亦然。
- connect by 子句:連接條件。prior 跟父節點列parentid放在一起,就是往父結點方向遍歷;prior 跟子結點列subid放在一起,則往葉子結點方向遍歷。parent_id、id兩列誰放在 “=” 前都無所謂,關鍵是prior跟誰在一起。
- order by 子句:排序。
常用的select項:
LEVEL:級別
connect_by_root:根節點
sys_connect_by_path:遞歸路徑
2.1 查詢所有子節點
select t.*,LEVELfrom area_test tstart with name ="鄭州市"connect by prior id=parent_id
其實,如果單層結構,使用表自身連接也可以實現:
select * from area_test t1,area_test t2 where t1.PARENT_ID = t2.ID and t2.name="鄭州市";
當查詢節點下有多層數據:
select t.*,LEVELfrom area_test tstart with name ="河南省"connect by prior id=parent_id
select * from area_test t1,area_test t2 where t1.PARENT_ID = t2.ID and t2.name="河南省";
如果使用自身連接,也只能查到子一級節點的數據,需要遍歷子一級節點,遞歸查詢每個子一級節點下的子節點。明顯麻煩很多?。?!
2.2 查詢所有父節點
select t.*,levelfrom area_test tstart with name ="鄭州市"connect by prior t.parent_id=t.idorder by level asc;
2.3 查詢指定節點的根節點
select d.*, connect_by_root(d.id) rootid, connect_by_root(d.name) rootnamefrom area_test dwhere name="二七區"start with d.parent_id IS NULLconnect by prior d.id=d.parent_id
select d.*, connect_by_root(d.id) rootid, connect_by_root(d.name) rootnamefrom area_test dstart with d.parent_id IS NULLconnect by prior d.id=d.parent_id
2.4 查詢下行政組織遞歸路徑
select id, parent_id, name, sys_connect_by_path(name, "->") namepath, levelfrom area_teststart with name = "平頂山市"connect by prior id = parent_id
3 with遞歸查詢
3.1 with遞歸子類
with tmp(id, parent_id, name) as ( select id, parent_id, name from area_test where name = "平頂山市" union all select d.id, d.parent_id, d.name from tmp, area_test d where tmp.id = d.parent_id )select * from tmp;
3.2 遞歸父類
with tmp(id, parent_id, name) as ( select id, parent_id, name from area_test where name = "二七區" union all select d.id, d.parent_id, d.name from tmp, area_test d where tmp.parent_id = d.id )select * from tmp;
4 MySQL 遞歸查找樹形結構
參考文章:MySQL 遞歸查找樹形結構,這個方法太實用了
參考文章:Oracle遞歸查詢
總結
到此這篇關于Oracle遞歸查詢樹形數據的文章就介紹到這了,更多相關Oracle遞歸查詢樹形數據內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!
標簽:
Oracle
排行榜