SQL рекурсивный запрос CTE, набор нечетных результатов SQL Server 2005 - PullRequest
0 голосов
/ 12 января 2010

Я пытаюсь написать рекурсивный запрос CTE в SQL Server 2005, но получаю странный набор результатов. Мой стол:

PairID  ChildID ParentID
900        1        2       
901        2        3       
902        3        4       

Это мой запрос CTE:

WITH TESTER (PairID, 
             ChildID, 
             ParentID, 
             Level)
AS (SELECT a.PairID, a.ChildID,a.ParentID, 0 AS Level
    FROM BusinessHierarchy AS a
    UNION ALL
    SELECT b.PairID, b.ChildID, b.ParentID, oh.Level + 1 AS Level
    FROM BusinessHierarchy AS b INNER JOIN
    TESTER AS oh ON b.ChildID =  oh.ParentID)
SELECT 
      x.PairID, 
      x.ChildID,
      x.ParentID,
      x.Level
 FROM TESTER AS x
 ORDER BY x.Level, x.ChildID, x.ParentID

Хорошо, теперь я получаю возврат набора данных, однако он не такой, как ожидалось, поскольку он содержит повторение следующим образом:

PairID  ChildID ParentID Level
900     1       2        0
901     2       3        0
902     3       4        0
...

900     2       3        1
901     3       4        1
...

900     3       4        2

Если бы кто-то мог объяснить мне, почему это происходит и как я мог бы это исправить, я был бы очень благодарен.

Что касается моего последнего вопроса, как бы мне пришлось изменить его для отображения начального childID с каждым из родителей следующим образом:

Original
PairID  ChildID ParentID Level
900     1       2        0
901     2       3        1
902     3       4        2

I want it displayed as:
PairID  ChildID ParentID Level
900     1       2        0
901     1       3        1
902     1       4        2

1 Ответ

1 голос
/ 12 января 2010

Ваша проблема - ваша отправная точка. Первая часть запроса CTE возвращает все строки (обратите внимание, что их уровень равен 0).

Тогда - Ваша следующая часть запроса пойдет и получит все связанные строки (что добавляет ваш предыдущий набор результатов).

Я заметил, однако, что у вас нет записи для идентификатора 4

если бы вы сделали, вот что вы бы сделали:

;WITH TESTER (PairID, ChildID, ParentID, Level) AS (
    SELECT
        a.PairID,
        a.ChildID,
        a.ParentID,
        0 AS Level
    FROM BusinessHierarchy AS a
    LEFT JOIN BusinessHierarchy a2 ON a.ParentID = a2.ChildID
    WHERE a2.PairID is null

    UNION ALL

    SELECT
        b.PairID,
        b.ChildID,
        b.ParentID,
        oh.Level + 1 AS Level
    FROM BusinessHierarchy AS b
    INNER JOIN TESTER AS oh ON b.ParentID =  oh.ChildID
)

SELECT 
    x.PairID, 
    x.ChildID,
    x.ParentID,
    x.Level
FROM TESTER AS x
ORDER BY x.Level, x.ChildID, x.ParentID

Также см. мой ответ на аналогичный вопрос , чтобы показать правильный порядок сортировки (с использованием пути)

...