WITH q (LevelId, Description, DescendantId, Descendant_Description) AS
(
SELECT LevelId, Description, LevelId, Description
FROM mytable
UNION ALL
SELECT t.LevelId, t.Description, q.DescendantId, q.Descendant_Description
FROM q
JOIN mytable t
ON t.ParentLevelId = q.LevelId
)
SELECT *
FROM q
ORDER BY
LevelId, DescendantId
Поскольку этот запрос возвращает все пары «предок-потомок» в системе (строит так называемое транзитивное замыкание ), все, что вам нужно, чтобы поставить его наоборот, это поменять местами поля и изменить порядок:
WITH q (LevelId, Description, DescendantId, Descendant_Description) AS
(
SELECT LevelId, Description, LevelId, Description
FROM mytable
UNION ALL
SELECT t.LevelId, t.Description, q.DescendantId, q.Descendant_Description
FROM q
JOIN mytable t
ON t.ParentLevelId = q.LevelId
)
SELECT DescendantId AS LevelId, Descendant_Description AS Description,
LevelId AS DescendantId, Description AS Descendant_Description
FROM q
ORDER BY
LevelId, DescendantId