層次化結構可以理解為樹狀資料結構,由節點構成。比如常見的組織結構由乙個總經理,多個副總經理,多個部門部長組成。再比如在生產製造中一件產品會有多個子零件組成。舉個簡單的例子,如下圖所示
汽車作為根節點,下面包含發動機和車身兩個子節點,而子節點又是由其他葉節點構成。(葉節點表示沒有子節點的節點)
假如我們要把這些產品資訊儲存到資料庫中,會形成如下資料表。
我們用 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...