ОБНОВЛЕНО - Это должно быть то, что вы ищете.
Использование рекурсивного 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