Предполагается, что вы используете SQL Server, кажется довольно простой рекурсией.Трудно протестировать без текстового примера, но попробуйте следующее:
;WITH Hierarchy AS
(
SELECT DISTINCT
RootID = T.ParentID,
DescendantID = T.ParentID,
Level = 0
FROM
Table2 AS T
WHERE
NOT EXISTS (SELECT 'records without parents' FROM Table2 AS N WHERE N.ChildID = T.ParentID)
UNION ALL
SELECT
RootID = H.RootID,
DescendantID = T.ChildID,
Level = H.Level + 1
FROM
Hierarchy AS H
INNER JOIN Table2 AS T ON H.DescendantID = T.ParentID
)
SELECT
H.RootID,
H.DescendantID,
H.Level
FROM
Hierarchy AS H
ORDER BY
H.RootID,
H.Level
Чтобы исключить записи из вашего Table1
, вы можете использовать NOT EXISTS
в конце или в рекурсии, в зависимости от ваших потребностей(остановка при рекурсии сделает недействительными задних потомков записей из Table1
).
РЕДАКТИРОВАТЬ: Для работы с образцами данных и временной таблицей:
IF OBJECT_ID('tempdb..#Table2') IS NOT NULL
DROP TABLE #Table2
CREATE TABLE #Table2 (
ChildID INT,
ParentID INT)
INSERT INTO #Table2 (
ChildID,
ParentID)
VALUES
(20000449, 20000448),
(20000450, 20000448),
(20000452, 20000448),
(20000543, 20000449),
(20000544, 20000449),
(20000490, 20000543),
(20000739, 20000490),
(20000740, 20000490),
(20000741, 20000490)
;WITH Hierarchy AS
(
SELECT DISTINCT
RootID = T.ParentID,
DescendantID = T.ParentID,
Level = 0
FROM
#Table2 AS T
WHERE
NOT EXISTS (SELECT 'records without parents' FROM #Table2 AS N WHERE N.ChildID = T.ParentID)
UNION ALL
SELECT
RootID = H.RootID,
DescendantID = T.ChildID,
Level = H.Level + 1
FROM
Hierarchy AS H
INNER JOIN #Table2 AS T ON H.DescendantID = T.ParentID
)
SELECT
H.RootID,
H.DescendantID,
H.Level
FROM
Hierarchy AS H
ORDER BY
H.RootID,
H.Level
Результат:
RootID DescendantID Level
20000448 20000448 0
20000448 20000449 1
20000448 20000450 1
20000448 20000452 1
20000448 20000543 2
20000448 20000544 2
20000448 20000490 3
20000448 20000739 4
20000448 20000740 4
20000448 20000741 4