2

次のような一連のデータがあります。

ID, Description, ParentID
1,  Savoury, -1
2,  Cheese, 1
3,  Pastry, 1
4,  Quiche, 1
5,  Sweet, -1
6,  Chocolate, 5
...

私がしようとしているのは、Web ブラウザーのブレッドクラム リンクに似た一連の結果を生成するストアド プロシージャを作成することです。次のようなものが理想的です...

ID, BreadCrumb
1, Savoury
2, Savoury >> Cheese
3, Savoury >> Pastry
4, Savoury >> Quiche
5, Sweet
6, Sweet >> Chocolate
...

チーズやペストリーなどのアイテムは、それ自体ではアイテムとしてリストされません (Sweet のように)。これまでのところ、動作する次のコードがありますが、ParentID があるかどうかに関係なく、すべてがリストされます。

With BreadCrumb AS 
(
SELECT CAST(a.Description AS VARCHAR(100)) AS Path, a.ID, a.ParentID
FROM FoodStuff a

UNION ALL

SELECT CAST(BreadCrumb.Path + ' >> ' + b.Description AS VARCHAR(100)) AS Path, b.ID, b.ParentID
FROM FoodStuff b
INNER JOIN BreadCrumb ON BreadCrumb.ID = b.ParentID

)

SELECT * FROM BreadCrumb
ORDER BY Path

正しい方向への微調整に感謝します。

前もってありがとう、ケブ

4

1 に答える 1

4

ルート項目に制限するには、再帰 CTE のアンカー部分に条件が必要です。

With BreadCrumb AS 
(
SELECT CAST(a.Description AS VARCHAR(100)) AS Path, a.ID, a.ParentID
FROM FoodStuff a
WHERE a.ParentID = -1 -- select roots only

UNION ALL

SELECT CAST(BreadCrumb.Path + ' >> ' + b.Description AS VARCHAR(100)) AS Path, b.ID, b.ParentID
FROM FoodStuff b
INNER JOIN BreadCrumb ON BreadCrumb.ID = b.ParentID
)

おそらくID = -1のレコードがないため、内部結合が処理する必要があるため、CTEの再帰的な半分で同様の条件は必要ありません。

ベスト プラクティスはさておき、ParentID などの値を持つことが許可されていない外部キーには、-1 ではなく NULL を使用することをお勧めします。

SQL Fiddle、@Conrad Frix 提供。

于 2013-04-25T19:57:55.210 に答える