【個人學習筆記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.巢狀集合
是書的作者認為用於樹建模最完美最高明的解決方案.
慚愧..太難..準備翻第二次書的時候再研究...