在處理樹形結構數據(如組織架構、地區劃分、分類目錄)時,傳統做法往往採用循環或游標進行遞歸查詢,不僅代碼冗長,效率也較低。自 SQL Server 2005 起,微軟引入了公用表表達式(CTE),配合 UNION ALL 即可優雅地實現遞歸查詢,無需顯式循環。
遞歸 CTE 由兩部分組成:錨點成員(Anchor Member)與遞歸成員(Recursive Member),透過 UNION ALL 連接。
WITH TreeCTE AS (
-- 錨點:起始節點
SELECT Id, PId, Area, 1 AS Level
FROM Areas
WHERE Id = 6 -- 指定子節點 ID
UNION ALL
-- 遞歸:向上尋找父節點
SELECT a.Id, a.PId, a.Area, t.Level + 1
FROM Areas a
INNER JOIN TreeCTE t ON t.PId = a.Id
)
SELECT Area FROM TreeCTE ORDER BY Level DESC;
WITH TreeCTE AS (
SELECT Id, PId, Area, 1 AS Level
FROM Areas
WHERE Id = 7 -- 指定父節點 ID
UNION ALL
SELECT a.Id, a.PId, a.Area, t.Level + 1
FROM Areas a
INNER JOIN TreeCTE t ON t.Id = a.PId
)
SELECT Area FROM TreeCTE ORDER BY Level;
若需將查詢結果合併為「中國 > 北京市 > 豐台區」格式,可搭配變量彙總:
DECLARE @Path VARCHAR(8000) = '';
WITH TreeCTE AS (
SELECT Id, PId, Area
FROM Areas WHERE Id = 6
UNION ALL
SELECT a.Id, a.PId, a.Area
FROM Areas a INNER JOIN TreeCTE t ON t.PId = a.Id
)
SELECT @Path = @Path + Area + ' > ' FROM TreeCTE ORDER BY Id;
SELECT Path = LEFT(@Path, LEN(@Path) - 3); -- 移除尾部分隔符
CREATE PROCEDURE dbo.usp_GetAreaPath
@StartId INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Result VARCHAR(8000) = '';
WITH TreeCTE AS (
SELECT Id, PId, Area FROM Areas WHERE Id = @StartId
UNION ALL
SELECT a.Id, a.PId, a.Area
FROM Areas a INNER JOIN TreeCTE t ON t.PId = a.Id
)
SELECT @Result = @Result + Area + ' > ' FROM TreeCTE ORDER BY Id;
SELECT AreaPath = CASE WHEN LEN(@Result) > 0
THEN LEFT(@Result, LEN(@Result) - 3)
ELSE '' END;
END;
表結構與示例數據:


OPTION (MAXRECURSION 0) 移除限制(謹慎使用)HierarchyID 資料類型(SQL Server 2008+)CTE 遞歸查詢是處理樹形數據的標準現代寫法,代碼簡潔、可讀性強、效能優異。掌握此技術可避免傳統循環帶來的維護困擾與效能瓶頸。