用 SQL 查詢/構建樹型(層次)資料
<?XML:NAMESPACE PREFIX = O />
什麼是層次/樹型是什麼概念?
If a table contains hierarchical data, then you can select rows in a hierarchical.
注:在Oracle裡稱為hierarchical queries,而為了方便理解,把它譯為層次/樹型查詢。
作用 & 特徵
通常用於查詢整個層次/樹型關係的資料。如:公司的架構體系裡面,表裡儲存了每一層職位的資訊,需要全部查出來;(樹的形式)一些順序型的記錄,像:A群由上海搬到北京,之後又搬到廣州,不久又搬到南京…。(單鏈表形式)
凡是在表裡存在以上形式的資料,都可以根據一個點,它所有關聯的資料通過一條SELECT語句一次過查詢出來。
示例
網上有太多的層次/樹型結構的例子,而且在Oracle官方文件裡也有很好的例子。因此本文從資料結構的角度去說明一下具體的用法,不涉及任何業務知識。
先看一張關係圖:
至於上圖的樹型,我們通常說成:1 是根節點;4的父節點是2,子節點有5、6;而像3、5、6…這些沒有子節點的節點稱為葉結點。(不同的描述有不同的說法,在文章繼續之前先統一一下說法)
用表把上面的圖存起來。
SQL程式碼
|
根據需求寫SQL:
查出 1 下面的所有成員:(順推)
SQL程式碼
|
查出 8 上面的所有成員:(逆推)
SQL程式碼
|
查出所有葉(Leaf)結點,沒有子節點的節點:
SQL程式碼
|
其它說明
調優
內部不斷根據子、父節點來查詢本表。資料量大的話,給表新增子、父節點兩個欄位的索引,會有很明顯的快速效果。
根節點
Oracle 提供了可以快速找到根節點的操作符,如下SQL:
SQL程式碼
|
如果指定一個節點開始查的話,ROOT就是指定的那個節點,直接用 START WITH 後面那個值就行。不過如果沒有指定一個節點,表裡有多棵樹,這個就很有用了。
迴圈關係
在記錄裡有迴圈關係,樹型有根和子節點,而沒有迴圈的關係。這裡簡單說明一下,迴圈是怎回事吧。如新增一條這樣的記錄:
SQL程式碼
|
在<?XML:NAMESPACE PREFIX = ST1 />1-7-8這條路徑製造一條迴圈記錄。之後從8開始逆推到上一層(會報錯):
SQL程式碼
|
這裡需要用到一個迴圈處理,如下:
SQL程式碼
|