Получить все связанные идентификаторы одной и той же таблицы для заданных идентификаторов (CTE) - PullRequest
0 голосов
/ 14 июня 2019

Существует таблица со следующей структурой (упрощенно):

RowID FK_RowID
1     3
2     1
3     11
4     2
5     4
6     1
7     8
8     9
9
10
11

Я хочу получить список всех связанных RowID, а также связанных RowID.

Например, мне нужны все связанные RowID для RowID 1, я ожидаю следующий список:

2
3
4
5
6
11

Я попробовал следующий CTE, но получаю только 2,3,6,11:

;WITH CTE 
       AS (
            SELECT RowID, FK_RowID, 1 AS Depth
            FROM tbl
            WHERE RowID = 1
            UNION ALL
            SELECT e.RowID, e.FK_RowID, CTE.Depth + 1 AS Depth
                    FROM CTE
                    INNER JOIN tbl AS e
                    ON e.RowID = CTE.FK_RowID
            WHERE CTE.Depth < 50
          )

SELECT DISTINCT RowID
FROM CTE
WHERE RowID <> 1
UNION 
SELECT RowID FROM tbl WHERE FK_RowID = 1

Это только получение прямого пути 1 -> 3 -> 11, но мне нужны и другие пути: 2 -> 4 -> 5

Есть идеи?

1 Ответ

2 голосов
/ 14 июня 2019

Вам необходимо пройти по иерархии в обоих направлениях:

DECLARE @ID int  = 1;

WITH VTE AS(
    SELECT *
    FROM (VALUES(1,3),
                (2,1),
                (3,11),
                (4,2),
                (5,4),
                (6,1),
                (7,8),
                (8,9),
                (9,NULL),
                (10,NULL),
                (11,NULL))V(RowID,FK_RowID)),
Children AS(
    SELECT V.RowID,
           V.FK_RowID
    FROM VTE V
    WHERE V.RowID = @ID
    UNION ALL
    SELECT V.RowID,
           V.FK_RowID
    FROM Children C
         JOIN VTE V ON C.RowID = V.FK_RowID),
Parents AS(
    SELECT V.RowID,
           V.FK_RowID
    FROM VTE V
    WHERE V.RowID = @ID
    UNION ALL
    SELECT V.RowID,
           V.FK_RowID
    FROM Parents P
         JOIN VTE V ON P.FK_RowID = V.RowID)
SELECT RowID
FROM Children
WHERE RowID != @ID
UNION ALL
SELECT RowID
FROM Parents
WHERE RowID != @ID;
...