Oracle遞迴查詢

2021-05-23 11:42:47 字數 3486 閱讀 8949

sql**

create

table  test_tree  

(  

id   number,  

pid  number,  

ind  number,  

name  varchar2(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

from  table_name  

start with

column =value  

connect

byprior  父主鍵=子外來鍵  

select column

from table_name

start with column=value

connect by prior 父主鍵=子外來鍵

對於本例來說,就是:

sql**

select    d.*    from   test_tree d   

start   with    d.pid=0  

connect

byprior    d.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**

select    d.*    from   test_tree d   

start   with    d.pid=0  

connect

byprior    d.id=d.pid   

order

by  d.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**

select    d.*    from   ( select  dd.*  from  test_tree dd  order

by  dd.ind) d   

start   with    d.pid=0  

connect

byprior    d.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**

select    d.*    from   test_tree d   

start   with    d.pid=0  

connect

byprior    d.id=d.pid   

order    siblings    by    d.ind    asc

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

這樣一來,查詢結果就完全符合我們的要求了。

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...