有的情況下,我們需要用遞迴的方法整理資料,這才程式中很容易做到,但是在資料庫中,用sql語句怎麼實現?下面我以最典型的樹形結構來說明下如何在oracle使用遞迴查詢。
為了說明方便,建立一張資料庫表,用於儲存乙個簡單的樹形結構
sql**
create
tabletest_tree
(
id number,
pid number,
ind number,
namevarchar2(32)
)
create table test_tree
( id number,
pid number,
ind number,
name varchar2(32)
)
id是主鍵,pid是父節點id,ind是排序字段,name是節點名稱。初始化幾條測試資料。
idpid
indname10
1根節點21
1一級選單131
2一級選單241
2一級選單352
1一級1子162
2一級1子274
1一級3子184
2一級3子294
3一級3子3104
0一級3子0
一、基本使用:
在oracle中,遞迴查詢要用到start with 。。。。connect by prior。。。
具體格式是:
sql**
select
column
fromtable_name
startwith
column=value
connect
by
prior父主鍵=子外來鍵
select column
from table_name
start with column=value
connect by prior 父主鍵=子外來鍵
對於本例來說,就是:
sql**
selectd.*fromtest_tree d
startwithd.pid=0
connect
by
priord.id=d.pid
select d.* from test_tree d
start with d.pid=0
connect by prior d.id=d.pid
查詢結果如下:
idpid
indname10
1根節點21
1一級選單152
1一級1子162
2一級1子231
2一級選單241
2一級選單374
1一級3子184
2一級3子294
3一級3子3104
0一級3子0
我們從結果中可以看到,記錄已經是按照樹形結構進行排列了,但是現在有個新問題,如果我們有這樣的需求,就是不但要求結果按照樹形結構顯示,還要根據ind欄位在每乙個分支內進行排序,這個問題怎麼處理呢?我們可能很自然的想到如下語句:
sql**
selectd.*fromtest_tree d
startwithd.pid=0
connect
by
priord.id=d.pid
order
byd.ind
select d.* from test_tree d
start with d.pid=0
connect by prior d.id=d.pid
order by d.ind
結果如下:
idpid
indname10
1根節點21
1一級選單152
1一級1子162
2一級1子241
2一級選單3104
0一級3子084
2一級3子294
3一級3子374
1一級3子131
2一級選單2
這顯然不是我們想要的結果,那下面的這個語句呢?
sql**
selectd.*from(selectdd.*fromtest_tree ddorder
bydd.ind) d
startwithd.pid=0
connect
by
priord.id=d.pid
select d.* from (select dd.* from test_tree dd order by dd.ind) d
start with d.pid=0
connect by prior d.id=d.pid
結果如下:
idpid
indname10
1根節點21
1一級選單152
1一級1子162
2一級1子241
2一級選單3104
0一級3子084
2一級3子294
3一級3子374
1一級3子131
2一級選單2
這個結果看似對了,但由於一級選單3節點下有乙個節點的ind=0,導致一級選單2被拍到了3下面。如果想使用類似這樣的語句做到各分支內排序,則需要找到乙個能夠準確描述選單級別的字段,但是對於示例表來說,不存在這麼乙個字段。
那我們如何實現需求呢?其實oracle9以後,提供了一種排序「order siblings by」就可以實現我們的需求,用法如下:
sql**
selectd.*fromtest_tree d
startwithd.pid=0
connect
by
priord.id=d.pid
ordersiblingsbyd.indasc
select d.* from test_tree d
start with d.pid=0
connect by prior d.id=d.pid
order siblings by d.ind asc
結果如下:
idpid
indname10
1根節點21
1一級選單152
1一級1子162
2一級1子231
2一級選單241
2一級選單3104
0一級3子074
1一級3子184
2一級3子294
3一級3子3
這樣一來,查詢結果就完全符合我們的要求了。
至於在oracle8以前版本,或者其他資料庫中如何實現類似的功能,希望大家來指教下,謝謝。
oracle 遞迴查詢 Oracle遞迴查詢
1.1 建立表與插入資料 create table district id number 10 not null,parent id number 10 name varchar2 255 byte not null alter table district add constraint distr...
oracle 逆向遞迴查詢 oracle遞迴查詢
oracle的遞迴查詢 最近在看公司的oa系統,oa系統中基本都會有節點樹,其中對於樹上的資料展示,就是用了資料庫的遞迴查詢,在這裡總結下遞迴查詢。現在存在如下的一棵樹 不會畫樹,將就一下,該樹對應下面建立的表資料。建立如下表 create table dg id number not null,主...
oracle 逆向遞迴查詢 Oracle遞迴查詢
start with.connect by子句遞迴查詢一般用於乙個表維護樹形結構的應用。建立示例表 create table tbl test id number,name varchar2 100 byte pid number default 0 插入測試資料 insert into tbl t...