已更新 - 這應該是你要找的。 使用遞歸CTE爲喬·斯特凡內利說:
表結構:
CREATE TABLE [HR].[Employees](
[empid] [int] IDENTITY(1,1) NOT NULL,
[lastname] [nvarchar](20) NOT NULL,
[firstname] [nvarchar](10) NOT NULL,
[mgrid] [int] NULL
);
樣本數據我使用:
empid lastname firstname mgrid
----------- -------------------- ---------- -----------
1 Davis Sara NULL
2 Funk Don 1
3 Lew Judy 2
4 Peled Yael 3
5 Buck Sven 2
6 Suurs Paul 5
7 King Russell 5
8 Cameron Maria 3
9 Dolgopyatova Zoya 5
查詢:
WITH RCTE AS (
SELECT NULL AS PrevEmpId,
NULL AS PrevMgrId,
E.empid AS CurEmpId,
E.mgrid AS CurMgrid,
0 AS [Level],
E.lastname AS LastName,
E.firstname AS FirstName
FROM HR.Employees AS E
WHERE E.mgrid IS NULL
UNION ALL
SELECT PREV.CurEmpId AS PrevEmpId,
PREV.CurMgrid AS PrevMgrId,
CUR.empid AS CurEmpId,
CUR.mgrid AS CurMgrId,
Prev.Level + 1 AS [Level],
CUR.lastname AS LastName,
CUR.firstname AS FirstName
FROM RCTE AS PREV
JOIN HR.Employees AS CUR ON CUR.mgrid = PREV.CurEmpId
),RAnecestors AS (
SELECT E.empid AS StartEmpId,
NULL AS PrevEmpId,
NULL AS PrevMgrId,
E.empid AS CurEmpId,
E.mgrid AS CurMgrid,
1 AS [LevelDiff],
E.lastname AS LastName,
E.firstname AS FirstName
FROM HR.Employees AS E
UNION ALL
SELECT PREV.StartEmpId AS StartEmpId,
PREV.CurEmpId AS PrevEmpId,
PREV.CurMgrid AS PrevMgrId,
CUR.empid AS CurEmpId,
CUR.mgrid AS CurMgrId,
Prev.[LevelDiff] + 1 AS [LevelDiff],
CUR.lastname AS LastName,
CUR.firstname AS FirstName
FROM RAnecestors AS PREV
JOIN HR.Employees AS CUR ON CUR.empid = PREV.CurMgrid
)
SELECT RCTE.CurEmpId AS CurrentID,
RCTE.LastName AS CurrentLastName,
RAnecestors.CurEmpId AS AncestorID,
RAnecestors.LastName AS AncestorLastName,
[Level] AS [Level],
[LevelDiff] - 1 AS [LevelDiff]
LEFT JOIN RAnecestors ON RAnecestors.StartEmpId = RCTE.CurEmpId
AND RCTE.CurEmpId <> RAnecestors.CurEmpId
ORDER BY RCTE.CurEmpId, RAnecestors.LevelDiff
輸出:
CurrentID CurrentLastName AncestorID AncestorLastName Level LevelDiff
----------- -------------------- ----------- -------------------- ----------- -----------
1 Davis NULL NULL 0 NULL
2 Funk 1 Davis 1 1
3 Lew 2 Funk 2 1
3 Lew 1 Davis 2 2
4 Peled 3 Lew 3 1
4 Peled 2 Funk 3 2
4 Peled 1 Davis 3 3
5 Buck 2 Funk 2 1
5 Buck 1 Davis 2 2
6 Suurs 5 Buck 3 1
6 Suurs 2 Funk 3 2
6 Suurs 1 Davis 3 3
7 King 5 Buck 3 1
7 King 2 Funk 3 2
7 King 1 Davis 3 3
8 Cameron 3 Lew 3 1
8 Cameron 2 Funk 3 2
8 Cameron 1 Davis 3 3
9 Dolgopyatova 5 Buck 3 1
9 Dolgopyatova 2 Funk 3 2
9 Dolgopyatova 1 Davis 3 3
什麼版本的SQL Server? 2005+可爲您提供[遞歸CTE](http://msdn.microsoft.com/zh-cn/library/ms186243.aspx)。 – 2012-01-27 21:55:34
對不起,我忘了版本,它是2008年 - 我用cte檢查是否有人在祖先線上,但檢查所有用戶之間的關係非常緩慢,應該有辦法從另一側做 – 2012-01-27 22:01:46
建立並返回內存表的T-SQL函數是否可行? – 2012-01-27 22:21:44