SQL 高階查詢(層次化查詢,遞迴)

2022-06-10 01:36:07 字數 2780 閱讀 1544

層次化結構可以理解為樹狀資料結構,由節點構成。比如常見的組織結構由乙個總經理,多個副總經理,多個部門部長組成。再比如在生產製造中一件產品會有多個子零件組成。舉個簡單的例子,如下圖所示

汽車作為根節點,下面包含發動機和車身兩個子節點,而子節點又是由其他葉節點構成。(葉節點表示沒有子節點的節點)

假如我們要把這些產品資訊儲存到資料庫中,會形成如下資料表。

我們用 parent_product_id 列表示當前產品的父產品是哪乙個。

那麼用 sql 語句如何進行層次化查詢呢?這裡就要用到 connect by 和 start with 語法。

我們先把 sql 寫出來,再來解釋其中的含義。

select

level,

id,parent_product_id,

name

from

product

start with id = 1

connect by prior id = parent_product_id

order by

level

查詢結果如下:

解釋一下:level 列表示當前產品屬於第幾層級。start with 表示從哪乙個產品開始查詢,connect by prior 表示父節點與子節點的關係,每乙個產品的 id 指向乙個父產品。

如果我們把 start with 的查詢起點改為 id = 2,重新執行上面的 sql 語句將會得到如下結果:

因為 id=2 的產品是車身,我們就只能查到車身下面的子產品。

當然,我們可以把查詢結果美化一下,使其更有層次感,我們讓根節點下面的 level 前面加幾個空格即可。把上面的 sql 稍微修改一下。為每個 level 前面增加 2*(level-1)個空格,這樣第二層就會增加兩個空格,第三層會增加四個空格。

select

level,

id,parent_product_id,

lpad(' ', 2 * (level - 1)) || name as name

from

product

start with id = 1

connect by prior id = parent_product_id

查詢結果已經有了層次感,如下圖:

除了使用上面我們說的方法,還可以使用遞迴查詢得到同樣的結果。遞迴會用到 with 語句。普通的 with 語句可以看作乙個子查詢,我們在 with 外部可以直接使用這個子查詢的內容。

當遞迴查詢時,我們是在 with 語句內部來引用這個子查詢。還是上面的例子,我們使用 with 語句來查詢。

with

temp_product (product_level, id, parent_product_id,name) as

( select

0 as product_level,id,parent_product_id,name

from

product

where

parent_product_id is null

union all

select

tp.product_level + 1,p.id,

p.parent_product_id,

p.name

from

product p

join temp_product tp

onp.parent_product_id=tp.id

)select

product_level,

id,parent_product_id,

lpad(' ', 2 * product_level)

|| name as name

from

temp_product;

第一條 select 語句我們查詢出來了根節點,並且設定為 level = 0,第二條select 語句關聯上 with 語句自身,並且 level 每層加 1 進行遞迴。

查詢結果如下:

可以看到第一列是展示的產品層級,和我們上面查詢出來的結果是一致的。

同時使用 with 遞迴時還可以使用深度優先搜尋和廣度優先搜尋,什麼意思呢?廣度優先就是在返回子行之前首先返回兄弟行,如上圖,首先把車身和發動機兩個兄弟行返回,之後是他們下面的子行。相反,深度優先就是首先返回乙個父節點的子行再返回另乙個兄弟行。

我們只需要在 select 語句上方加上下面語句即可實現深度優先搜尋查詢。

search depth first by id

set order_by_id

結果如下,看到首先返回每個父節點下的子行,再返回另乙個父節點。

同理,廣度優先使用的是下面的 sql 語句

search breadth first by id

set order_by_id

SQL 高階查詢 (層次化查詢,遞迴)

遞迴會用到 with 語句。普通的 with 語句可以看作乙個子查詢,我們在 with 外部可以直接使用這個子查詢的內容。當遞迴查詢時,我們是在 with 語句內部來引用這個子查詢。還是上面的例子,我們使用 with 語句來查詢。with temp product product level,id,...

oracle 層次化查詢

1 層次化查詢 層次化 同一資料庫表中多條資料存在父子關係,形成樹狀結構。利用connect by 進行層次化查詢 按照某種規則,獲得節點路徑上的節點集合。如 select from market b start with b m id 10 b connect by prior b p id m ...

Oracle 層次化查詢

create table employees employee id integer constraint employees pk primary key,manager id integer constraint employees fk employees references employe...