Oracle遞迴查詢

2021-05-22 11:33:12 字數 4312 閱讀 2554

有的情況下,我們需要用遞迴的方法整理資料,這才程式中很容易做到,但是在資料庫中,用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...