2009-10-05 1 views
0

У меня есть таблица категорий, похожее на это:Помощь с рекурсивных SQL

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 

И так далее. КТР являются, как это 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) 

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

ответ

1

Использование 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 
3

Использование 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

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