程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> oracle樹形查詢 start with connect by,oracleconnect

oracle樹形查詢 start with connect by,oracleconnect

編輯:Oracle教程

oracle樹形查詢 start with connect by,oracleconnect


一、簡介
  在oracle中start with connect by (prior) 用來對樹形結構的數據進行查詢。其中start with conditon 給出的是數據搜索范圍, connect by後面給出了遞歸查詢的條件,prior 關鍵字表示父數據,prior 條件表示子數據需要滿足父數據的什麼條件。如下
start with id= '10001' connect by prior parent_id= id and prior num = 5
表示查詢id為10001,並且遞歸查詢parent_id=id,為5的記錄。
二、實例
  1、構造數據

 1 -- 表結構
 2 create table menu(
 3  id varchar2(64) not null,
 4  parent_id varchar2(64) not null,
 5  name varchar2(100) not null,
 6  depth number(2) not null,
 7  primary key (id)
 8 )
 9 
10 -- 初始化數據
11 -- 頂級菜單
12 insert into menu values ('100000', '0', '頂級菜單1', 1);
13 insert into menu values ('200000', '0', '頂級菜單2', 1);
14 insert into menu values ('300000', '0', '頂級菜單3', 1); 
15 
16 -- 父級菜單
17 -- 頂級菜單1 直接子菜單
18 insert into menu values ('110000', '100000', '菜單11', 2);
19 insert into menu values ('120000', '100000', '菜單12', 2);
20 insert into menu values ('130000', '100000', '菜單13', 2);
21 insert into menu values ('140000', '100000', '菜單14', 2); 
22 -- 頂級菜單2 直接子菜單
23 insert into menu values ('210000', '200000', '菜單21', 2);
24 insert into menu values ('220000', '200000', '菜單22', 2);
25 insert into menu values ('230000', '200000', '菜單23', 2); 
26 -- 頂級菜單3 直接子菜單
27 insert into menu values ('310000', '300000', '菜單31', 2); 
28 
29 -- 菜單13 直接子菜單
30 insert into menu values ('131000', '130000', '菜單131', 3);
31 insert into menu values ('132000', '130000', '菜單132', 3);
32 insert into menu values ('133000', '130000', '菜單133', 3);
33 
34 -- 菜單132 直接子菜單
35 insert into menu values ('132100', '132000', '菜單1321', 4);
36 insert into menu values ('132200', '132000', '菜單1332', 4);
37  

  生成的菜單層次結構如下:
頂級菜單1
          菜單11
          菜單12
          菜單13
                    菜單131
                    菜單132
                              菜單1321
                              菜單1322
                    菜單133
          菜單14
頂級菜單2
          菜單21
          菜單22
          菜單23
頂級菜單3
          菜單31

  2、SQL查詢

--prior放的左右位置決定了檢索是自底向上還是自頂向下. 左邊是自上而下(找子節點),右邊是自下而上(找父節點)
--找父節點
select * from menu start with id='130000' connect by id = prior parent_id;

  

--找子節點節點
-- (子節點)id為130000的菜單,以及130000菜單下的所有直接或間接子菜單(prior 在左邊, prior、parent_id(等號右邊)在右邊)
select * from menu start with id='130000' connect by prior id =  parent_id  ;

  

-- (父節點)id為1321的菜單,以及1321菜單下的所有直接或間接父菜單(prior、parent_id(等號左邊) 都在左邊)
select * from menu start with id='132100' connect by prior parent_id = id;
-- prior 後面跟的是(parent_id) 則是查找父節點,prior後面跟的是(id)則是查找子節點

  

-- 查詢所有的葉子節點
select t2.* from menu t2 where id not in(select t.parent_id from menu t) order by id;

  

三、性能問題  

   對於 start with connect by語句的執行,oracle會進行遞歸查詢,當數據量大的時候會產生性能相關問題。

--生成執行計劃
explain plan for select * from menu start with id='132100' connect by prior parent_id = id;

-- 查詢執行計劃
select *  from  table( dbms_xplan.display);

  語句執行計劃結果如下:

Plan hash value: 3563250490
 
----------------------------------------------------------------------------------------------
| Id  | Operation                     | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |              |     1 |   133 |     1   (0)| 00:00:01 |
|*  1 |  CONNECT BY WITH FILTERING    |              |       |       |            |          |
|   2 |   TABLE ACCESS BY INDEX ROWID | MENU         |     1 |   133 |     1   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN          | SYS_C0018586 |     1 |       |     1   (0)| 00:00:01 |
|   4 |   NESTED LOOPS                |              |       |       |            |          |
|   5 |    CONNECT BY PUMP            |              |       |       |            |          |
|   6 |    TABLE ACCESS BY INDEX ROWID| MENU         |     1 |   133 |     1   (0)| 00:00:01 |
|*  7 |     INDEX UNIQUE SCAN         | SYS_C0018586 |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("ID"=PRIOR "PARENT_ID")
   3 - access("ID"='132100')
   7 - access("ID"=PRIOR "PARENT_ID")
 
Note
-----
   - dynamic sampling used for this statement

  通過該執行計劃得知,改語句執行了7步操作,才將結果集查詢並返回。當需要查詢條件進行過濾的時候,我們可以通過查看執行計劃從而對sql進行優化。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved