1. 程式人生 > >【個人學習筆記11之--SQL 中的 圖 樹 層次結構】

【個人學習筆記11之--SQL 中的 圖 樹 層次結構】

在RDBMS中操作 圖 樹 層次結構 等特殊的資料結構時,我們通常採用2個主要方法:
1.基於迭代/遞迴

2.具體化描述資料結構的附加資訊
一般模型有:員工組織圖(樹,層次結構);料表--BOM(有向圖);道路系統(無向迴圈圖)


1.迭代/遞迴
迭代可以迭代圖的一個節點,也可以迭代一個層次.後者比前者要快很多.
實現方法:SQL2000通過UDF(使用者自定義函式),SQL2005使用CTE

a.下屬問題(通俗說,求子節點)
--這裡我使用書上的員工表(表內容如下)


--SQL2000 udf方法:

--SQL2005 CTE

--查詢結果


---------------如果需要限制遞迴的層數------------


--SQL2000

--查詢結果


SELECT empid, lvl
FROM dbo.fn_subordinates2(2, NULL) AS S;


PS:這裡控制返回的層數 你當然可以用最開始的方法,然後再篩選語句裡控制層數
 如SELECT empid, lvl FROM dbo.fn_subordinates1(3) AS S where lvl<3;  但是控制本身的遞迴只能在UDF裡面了
 
 --sql2005方法類似


--還有一種偏方:但是不推薦 雖然結果正確 但是會報錯

--查詢結果

 
 


b.祖先(通俗說:求父節點)
其實思路跟子節點差不多


--SQL2000


--查詢結果


SELECT empid, lvl
FROM dbo.fn_managers(8, 2) AS M;

--sql2005

C.層次顯示

--SQL2000,思路跟下屬問題一模一樣 只是多了個PATH

--這裡的顯示分2種
--顯示1
select empid ,pos=REPLICATE('-',lvl)+rtrim(empid)
FROM dbo.fn_subordinates3(1, NULL) AS S
ORDER BY PATH


--還有一種
SELECT empid,  path
FROM dbo.fn_subordinates3(1, NULL) AS S
ORDER BY PATH

--當然上面的顯示方式還很多,自己可以控制 比如不加ORDER 就可以排出不一樣的

--SQL2005
;

--結果查詢

D.檢測迴圈中異常
說白了 就是檢查表裡有沒出現1-2-4-1這種頭接尾的圈.這在現實中是不可能的.一個經理部可能是它手下的手下.-- ||
我們對錶做手腳,把老大的經理改成是它的一個員工

--查詢結果


--這樣管理員可以輕易找到那個錯誤的地方.
改過來:UPDATE dbo.Employees SET mgrid = NULL WHERE empid = 1;

2.具體化路徑
這裡就是新增加2列,一列是級別 一列是節點路徑,這樣可以避免每次都去計算.
2個優點:不需要遞迴,只需要基於集合 ;查詢可以使用到路徑索引

a.維護資料


1.新增不管理員工的員工
;
----檢測
SELECT empid, mgrid, empname, salary, lvl, path
FROM dbo.Employees
ORDER BY path;

2.移動子樹
比如說某個部門來了個新老大,原來部門老大和手下的人都要跟著他.這個時候表裡的路徑和級別都要更新
Select Empid, Replicate(' | ', Lvl) + Empname As Empname, Lvl, Path
From Dbo.Employees
Order By Path;

--這個是移動之前的層次分佈

==接下來我們移動

--移動後結果


--這個是移動之後 大家注意觀察7 和 10 兩位同志

3.移除子樹
就是把某個部門從公司取消掉
--首先檢視公司部門當前分佈

--查詢結果

--接著我們來開始一個部門 比如移除Aaron手下的人


--查詢結果

4.查詢


這裡的查詢可就輕鬆多啦 ~因為路徑都有啦~
--查詢EMPID為3的手下一批人


--查詢結果

b.巢狀集合
是書的作者認為用於樹建模最完美最高明的解決方案.
慚愧..太難..準備翻第二次書的時候再研究...