關於SQLServer2005的學習筆記——樹形結構
從功能上講的話,表函式方式更為靈活一些,畢竟基於過程的結構方式更容易實現負責的業務邏輯;但遞迴CTE構造起來更為清晰一些。
該文起源於《Microsoft SQL Server 2005技術內幕:T-SQL查詢》,但與文中所述不盡相同。
首先構建一個標準的樹形結構的員工表
CREATE TABLE Employees ( EmpID INT, MgrID INT, EmpName VARCHAR(25), Salary MONEY, CHECK(EmpID<>MgrID) ); GO INSERT INTO Employees VALUES(1,NULL,'David',10000); INSERT INTO Employees VALUES(2,1,'Eitan',7000); INSERT INTO Employees VALUES(3,1,'Ina',7500); INSERT INTO Employees VALUES(4,2,'Seraph',5000); INSERT INTO Employees VALUES(5,2,'Jiru',5500); INSERT INTO Employees VALUES(6,2,'Steve',4500); INSERT INTO Employees VALUES(7,3,'Aaron',5000); INSERT INTO Employees VALUES(8,5,'Lilach',3500); INSERT INTO Employees VALUES(9,7,'Rita',3000); INSERT INTO Employees VALUES(10,5,'Sean',3000); INSERT INTO Employees VALUES(11,7,'Gabriel',3000); INSERT INTO Employees VALUES(12,9,'Emilia',2000); INSERT INTO Employees VALUES(13,9,'Michael',2000); INSERT INTO Employees VALUES(14,9,'Didi',1500); |
--讓我們先來看看Oracle是如何實現的吧
--獲取所有相關員工資訊,並構建其級別和相應的結構指向 SELECT EmpID,MgrID,EmpName,Salary,Level,sys_connect_by_path(NVL(EmpID,'0'),'->') FROM Employees CONNECT BY PRIOR EmpID=MgrID START WITH MgrID IS NULL --獲取員工的所有下級節點 SELECT EmpID,MgrID,EmpName,Salary,Level FROM Employees CONNECT BY PRIOR EmpID=MgrID START WITH EmpID=9 --獲取員工的所有上級節點 SELECT EmpID,MgrID,EmpName,Salary,Level FROM Employees CONNECT BY PRIOR MgrID=EmpID START WITH EmpID=14 |
--構建遞迴CTE,也可以靈活獲取滿足不同級別的上下級節點
WITH EmployeeTree AS ( SELECT EmpID,MgrID,EmpName,Salary, 0 AS Level, CAST(CASE WHEN MgrID IS NULL THEN 'Root' END AS VARCHAR(50)) MgrList FROM Employees WHERE MgrID IS NULL --此處亦可修改為MgrID=@Root,即傳入的節點,即可得到想要的節點內容 UNION ALL SELECT C.EmpID,C.MgrID,C.EmpName,C.Salary, P.Level+1 AS Level, CAST(CAST(P.MgrList AS VARCHAR(50))+'->'+CAST(C.EmpID AS VARCHAR(10)) AS VARCHAR(50)) MgrList FROM EmployeeTree P,Employees C WHERE C.MgrID=P.EmpID --AND P.Level<2 設定相關級別 ) --所有員工 SELECT * FROM EmployeeTree --求某員工上級 SELECT * FROM EmployeeTree WHERE CHARINDEX(MgrList,(SELECT MgrList FROM EmployeeTree WHERE EmpID=7))>0 --求某員工下級 SELECT * FROM EmployeeTree WHERE MgrList LIKE (SELECT MgrList FROM EmployeeTree WHERE EmpID=7)+'%' --求某員工下級並且符合相應級數的 SELECT * FROM EmployeeTree WHERE MgrList LIKE (SELECT MgrList FROM EmployeeTree WHERE EmpID=7)+'%' AND Level<=(SELECT Level FROM EmployeeTree WHERE EmpID=7)+1 |
--透過表函式方式返回相關節點
CREATE FUNCTION fn_GetEmployeeTree(@root AS INT) RETURNS @Subs TABLE ( EmpID INT, Level INT ) AS BEGIN DECLARE @Level AS INT; SET @Level=0; INSERT INTO @Subs(EmpID,Level) SELECT EmpID,@Level FROM Employees WHERE EmpID=@root;
WHILE @@rowcount>0 BEGIN SET @Level=@Level+1; INSERT INTO @Subs(EmpID,Level) SELECT C.EmpID,@Level FROM @SubS AS P JOIN Employees AS C ON P.Level=@Level-1 AND C.MgrID=P.EmpID END
RETURN;
END SELECT * FROM fn_GetEmployeeTree(1) |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-626347/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於SQLServer2005的學習筆記(一)——前言SQLServer筆記
- 關於SQLServer2005的學習筆記——生日問題SQLServer筆記
- 關於SQLServer2005的學習筆記——子查詢SQLServer筆記
- 關於SQLServer2005的學習筆記——分析函式SQLServer筆記函式
- 關於SQLServer2005的學習筆記——XML的處理SQLServer筆記XML
- 關於SQLServer2005的學習筆記——SQL查詢解析步驟SQLServer筆記
- 關於SQLServer2005的學習筆記——自定義分組的實現SQLServer筆記
- 資料結構——李超線段樹 學習筆記資料結構筆記
- [學習筆記] Splay & Treap 平衡樹 - 資料結構筆記資料結構
- 【學習筆記】Kruskal 重構樹筆記
- kruskal重構樹學習筆記筆記
- 關於SQLServer2005的學習筆記——異常捕獲及處理SQLServer筆記
- 設計模式學習筆記(十三)組合模式及其在樹形結構中的應用設計模式筆記
- 關於SQLServer2005的學習筆記——臨時表、表變數和CTESQLServer筆記變數
- 關於SQLServer2005的學習筆記——多觸發器執行問題SQLServer筆記觸發器
- Go 結構 學習筆記Go筆記
- 樹形結構
- 關於http(自己的學習筆記)HTTP筆記
- 關於SQLServer2005的學習筆記——CTE遞迴和模擬測試資料SQLServer筆記遞迴
- 關於SQLServer2005的學習筆記——約束、Check、觸發器的執行順序SQLServer筆記觸發器
- swift 關於 toolbar 學習筆記Swift筆記
- GO 學習筆記->結構體Go筆記結構體
- 資料結構學習筆記資料結構筆記
- 樹的學習——樹的儲存結構
- [筆記]樹形dp筆記
- Myth 關於Git的學習筆記Git筆記
- 平衡樹學習筆記筆記
- 支配樹學習筆記筆記
- 平衡樹 學習筆記筆記
- layui樹形結構UI
- java樹形結構Java
- 關於結構體型別的學習結構體型別
- 關於資料結構的學習心得資料結構
- 結構動力學教材-學習筆記筆記
- 資料結構和演算法學習筆記十六:紅黑樹資料結構演算法筆記
- 關於elementUI樹狀結構的bugUI
- Oracle體系結構學習筆記Oracle筆記
- 資料結構學習筆記--棧資料結構筆記