B tree結構選單的遞迴查詢

2022-05-09 09:57:14 字數 3020 閱讀 4502

有層次結構的選單樹,後台庫表結構通常會設計為b-tree結構,

通過這種自關聯的方式隱含樹的層次結構,如:

create

table

t_menu(

id

number, --

節點號--

name varchar2(50),

pid number

default0--

父節點號。0為根節點,不存在id=0的節點

);insert

into t_menu (id, pid) values ('

1', '0'

);insert

into t_menu (id, pid) values ('

2', '1'

);insert

into t_menu (id, pid) values ('

3', '1'

);insert

into t_menu (id, pid) values ('

4', '2'

);insert

into t_menu (id, pid) values ('

5', '2'

);insert

into t_menu (id, pid) values ('

6', '3'

);insert

into t_menu (id, pid) values ('

7', '3'

);insert

into t_menu (id, pid) values ('

8', '5'

);insert

into t_menu (id, pid) values ('

9', '5'

);insert

into t_menu (id, pid) values ('

10', '7'

);insert

into t_menu (id, pid) values ('

11', '7'

);insert

into t_menu (id, pid) values ('

12', '10'

);insert

into t_menu (id, pid) values ('

13', '10'

);select

*from t_menu t order

by t.id asc;

上面初始化的資料,其樹形結構如下:

這種結構的選單資料,該如何查詢呢,通常來說,我們會有兩種查詢場景:

這兩個查詢,可通過sql的 start with ... connect by prior 遞迴查詢法查詢

select t.id, t.pid, level

from

t_menu t

start

with t.pid ='7

'connect

by prior t.id =

t.pid

order

bylevel

asc;

查詢結果如下:

idpid

level107

11171

1210213

10

select t.id, t.pid, level

from

t_menu t

start

with t.id ='7

'connect

by t.id =

prior t.pid

order

bylevel

desc;

查詢結果如下:

idpid

level10

3312

731start with 子句: 這是遍歷的起始條件,也是遍歷結果中第一層(level = 1)的資料條件。connect by prior 子句: 這是表自關聯的連線條件,prior欄位是已有資料行的字段,用它與表中其它行的非prior欄位進行關聯。connect by 後邊可以有多個條件,每個條件都可以有或沒有prior關鍵字.

自關聯遞迴是如何進行的呢?根據start with 條件找到起始記錄後,在起始記錄中取prior欄位的值,然後在本表中查詢這樣的資料行:它的非prior字段值與起始記錄的prior字段值 之間的關係,符合connect by 條件.

以上面例子中的向下遍歷為例,具體地,先根據起始條件找到pid = '7'的記錄,有兩條,分別是id = 10 和 id = 11,這是查詢的起始記錄,也就是第一層.然後連線條件是

prior t.id = t.pid 

那是說要查詢pid = 起始記錄的id值(即10和11) 的資料,沒有pid = 11的記錄,pid = 10的記錄有兩條,即id 為12 和13 的記錄,這就是查詢結果的第二層,以此類推,以第二層記錄為起始記錄,查詢pid=12或13的記錄,為第三層,這裡沒有第三層資料,遞迴結束.

在oracle中有一種與此等效的寫法,就是使用with as 語句遞迴查詢,這種寫法顯式地進行了遞迴自關聯查詢,其查詢過程與上面語法十分相似,可以通過分析這種寫法來理解上面的語法含義.

下面把上述例子中的向上遍歷sql,改寫為with as 遞迴寫法:

with tmp(id, pid) as

(select

t.id, t.pid

from

t_menu t

where t.id ='7

'union

allselect

b.id, b.pid

from

tmp a, t_menu b

where a.pid =

b.id)

select m.id, m.pid, rownum from tmp m order

by rownum desc;

ORACLE 遞迴查詢 選單樹

建立表 建表語句 create table sc district id number 10 not null,parent id number 10 name varchar2 255 byte not null alter table sc district add constraint sc ...

遞迴實現層級查詢選單

在層級查詢選單時意見有所分歧,想法有兩種一種是動態查詢,但是會增加伺服器的壓力,另一種方法是全部返回的資料,由前端去控制展示效果。層級查詢樹狀選單,想到使用遞迴去做遍歷查詢,在此記錄一下 實體類和到層就不再生成 核心 是service層的邏輯處理主要包括兩部分內容 層級獲取選單 public lis...

springboot 實現遞迴查詢選單

1.模型 tableid value id type idtype.auto private integer id 選單名稱 private string name 對映父id private integer parentid tablefield exist false private listt...