Помогите с рекурсивным SQL - PullRequest
       8

Помогите с рекурсивным SQL

0 голосов
/ 06 октября 2009

У меня есть таблица категорий, подобная этой:

   uid | ParentLevel | ParentID | Name
   ------------------------------------
    1  |       0     |      0   |  foo
    2  |       1     |      1   |  blat
    3  |       1     |      1   |  baz
    4  |       2     |      3   |  blah
    5  |       0     |      0   |  bar

Я пытаюсь получить вывод, похожий на этот:

1 | foo
2 | foo | blat
3 | foo | baz
4 | foo | baz | blah
5 | bar

И так далее. CTE отсутствуют, так как это SQL 2000. Я пробовал что-то подобное, но не могу понять, что это правильно:

SELECT     c1.uid, c1.Name, c2.Name AS Expr1, c3.Name AS Expr2
FROM         dbo.Categories AS c1 INNER JOIN
                  dbo.Categories AS c2 ON c1.uid = c2.ParentID INNER JOIN
                  dbo.Categories AS c3 ON c2.uid = c3.ParentID
WHERE     (c1.ParentLevel = 0) AND (c2.ParentLevel = 1) AND (c3.ParentLevel = 2)

Это вернет записи, только если есть третий уровень, который не всегда верен. Есть ли способ сделать это?

Ответы [ 3 ]

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

Использование LEFT JOIN

SELECT     c1.uid, c1.Name, c2.Name AS Expr1, c3.Name AS Expr2
FROM         dbo.Categories AS c1 LEFT JOIN 
                  dbo.Categories AS c2 ON c1.uid = c2.ParentID LEFT JOIN 
                  dbo.Categories AS c3 ON c2.uid = c3.ParentID
WHERE     (c1.ParentLevel = 0) AND (c2.ParentLevel = 1) AND (c3.ParentLevel = 2)
1 голос
/ 06 октября 2009

LEFT JOIN поможет вам получить ожидаемый результат. INNER JOIN объединяет только те записи, которые соответствуют другому результату запроса.

1 голос
/ 06 октября 2009

Используйте LEFT JOIN вместо INNER JOIN и перемещайте условия на уровне от WHERE до JOIN условия

SELECT      c1.uid, c1.Name, c2.Name AS Expr1, c3.Name AS Expr2
FROM        dbo.Categories AS c1 
LEFT JOIN   dbo.Categories AS c2 
        ON  c1.uid = c2.ParentID
        AND c2.ParentLevel = 1
LEFT JOIN   dbo.Categories AS c3 
        ON  c2.uid = c3.ParentID
        AND c3.ParentLevel = 2
WHERE       c1.ParentLevel = 0
...