-->Title:Generating test data -->Author:wufeng4552 -->Date :2009-09-30 08:52:38 set nocount on if object_id('tb','U')is not null drop table tb go create table tb(ID int, ParentID int) insert into tb select 1,0 insert into tb select 2,1 insert into tb select 3,1 insert into tb select 4,2 insert into tb select 5,3 insert into tb select 6,5 insert into tb select 7,6 -->Title:查找指定節點下的子結點 if object_id('Uf_GetChildID')is not null drop function Uf_GetChildID go create function Uf_GetChildID(@ParentID int) returns @t table(ID int) as begin insert @t select ID from tb where ParentID=@ParentID while @@rowcount<>0 begin insert @t select a.ID from tb a inner join @t b on a.ParentID=b.id and not exists(select 1 from @t where id=a.id) end return end go select * from dbo.Uf_GetChildID(5) /* ID ----------- 6 7 */ -->Title:查找指定節點的所有父結點 if object_id('Uf_GetParentID')is not null drop function Uf_GetParentID go create function Uf_GetParentID(@ID int) returns @t table(ParentID int) as begin insert @t select ParentID from tb where ID=@ID while @@rowcount!=0 begin insert @t select a.ParentID from tb a inner join @t b on a.id=b.ParentID and not exists(select 1 from @t where ParentID=a.ParentID) end return end go select * from dbo.Uf_GetParentID(2) /* ParentID ----------- 1 0 */ USE tempdb GO -- 建立演示環境 CREATE TABLE Dept( id int PRIMARY KEY, parent_id int, name nvarchar(20)) INSERT Dept SELECT 0, 0, N'<全部>' UNION ALL SELECT 1, 0, N'財務部' UNION ALL SELECT 2, 0, N'行政部' UNION ALL SELECT 3, 0, N'業務部' UNION ALL SELECT 4, 0, N'業務部' UNION ALL SELECT 5, 4, N'銷售部' UNION ALL SELECT 6, 4, N'MIS' UNION ALL SELECT 7, 6, N'UI' UNION ALL SELECT 8, 6, N'軟件開發' UNION ALL SELECT 9, 8, N'內部開發' GO -- 查詢指定部門下面的所有部門 DECLARE @Dept_name nvarchar(20) SET @Dept_name = N'MIS' ;WITH DEPTS AS( -- 定位點成員 SELECT * FROM Dept WHERE name = @Dept_name UNION ALL -- 遞歸成員, 通過引用CTE自身與Dept基表JOIN實現遞歸 SELECT A.* FROM Dept A, DEPTS B WHERE A.parent_id = B.id ) SELECT * FROM DEPTS GO -- 刪除演示環境 DROP TABLE Dept ----CTE的綜合應用 USE tempdb GO -- 建立演示環境 CREATE TABLE Dept( id int PRIMARY KEY, parent_id int, name nvarchar(20)) INSERT Dept SELECT 0, 0, N'<全部>' UNION ALL SELECT 1, 0, N'財務部' UNION ALL SELECT 2, 0, N'行政部' UNION ALL SELECT 3, 0, N'業務部' UNION ALL SELECT 4, 0, N'業務部' UNION ALL SELECT 5, 4, N'銷售部' UNION ALL SELECT 6, 4, N'MIS' UNION ALL SELECT 7, 6, N'UI' UNION ALL SELECT 8, 6, N'軟件開發' UNION ALL SELECT 9, 8, N'內部開發' GO -- 查詢指定部門下面的所有部門, 並匯總各部門的下級部門數 DECLARE @Dept_name nvarchar(20) SET @Dept_name = N'MIS' ;WITH DEPTS AS( -- 查詢指定部門及其下的所有子部門 -- 定位點成員 SELECT * FROM Dept WHERE name = @Dept_name UNION ALL -- 遞歸成員, 通過引用CTE自身與Dept基表JOIN實現遞歸 SELECT A.* FROM Dept A, DEPTS B WHERE A.parent_id = B.id ), DEPTCHILD AS( -- 引用第1個CTE,查詢其每條記錄對應的部門下的所有子部門 SELECT Dept_id = P.id, C.id, C.parent_id FROM DEPTS P, Dept C WHERE P.id = C.parent_id UNION ALL SELECT P.Dept_id, C.id, C.parent_id FROM DEPTCHILD P, Dept C WHERE P.id = C.parent_id ), DEPTCHILDCNT AS( -- 引用第2個CTE, 匯總得到各部門下的子部門數 SELECT Dept_id, Cnt = COUNT(*) FROM DEPTCHILD GROUP BY Dept_id ) SELECT -- JOIN第1,3個CTE,得到最終的查詢結果 D.*, ChildDeptCount = ISNULL(DS.Cnt, 0) FROM DEPTS D LEFT JOIN DEPTCHILDCNT DS ON D.id = DS.Dept_id GO -- 刪除演示環境 DROP TABLE Dept
