Иерархический запрос в SQL Server 2005 - PullRequest
0 голосов
/ 01 октября 2009

У меня есть структура данных внутри таблицы в SQL Server 2005, представляющая цепочку связанных объектов. Каждый объект может иметь замены на многих этапах. Я хочу выполнить запрос, который возвращает все объекты и лист каждого объекта в цепочке замены.

Данные:

id  replacement
1   null
2   3
3   null
4   5
5   6
6   null

Результат должен быть:

id  replacement
1   null
2   3
3   null
4   6
5   6
6   null

Я считаю, что рекурсивный CTE был бы хорошим способом, но я не могу обернуть его вокруг. Проблема заключается в том, что я не могу изменить структуру данных, поскольку база данных не находится под моим контролем.

1 Ответ

3 голосов
/ 01 октября 2009

Посмотрите на это

DECLARE @Table TABLE(
        ID INT,
        ReplacementID INT
)

INSERT INTO @Table (ID,ReplacementID) SELECT 1, NULL
INSERT INTO @Table (ID,ReplacementID) SELECT 2, 3
INSERT INTO @Table (ID,ReplacementID) SELECT 3, NULL
INSERT INTO @Table (ID,ReplacementID) SELECT 4, 5
INSERT INTO @Table (ID,ReplacementID) SELECT 5, 6
INSERT INTO @Table (ID,ReplacementID) SELECT 6, NULL

INSERT INTO @Table (ID,ReplacementID) SELECT 7, 8
INSERT INTO @Table (ID,ReplacementID) SELECT 8, 9
INSERT INTO @Table (ID,ReplacementID) SELECT 9, 10
INSERT INTO @Table (ID,ReplacementID) SELECT 10, NULL

SELECT * FROM @Table

;WITH repl AS (
    SELECT  *, 1 AS Depth
    FROM    @Table t
    UNION   ALL
    SELECT  r.ID,
            t.ReplacementID,
            r.Depth + 1
    FROM    repl r INNER JOIN
            @Table t ON r.ReplacementID = t.ID
    WHERE   t.ReplacementID IS NOT NULL
)
SELECT  repl.ID,
        repl.ReplacementID
FROM    (
            SELECT  ID,
                    MAX(Depth) Depth
            FROM    repl
            GROUP BY ID
        ) Depths INNER JOIN
        repl    ON  Depths.ID = repl.ID
                AND Depths.Depth = repl.Depth
ORDER BY 1
...