通常、この種の問題については、共通テーブル式を使用した再帰クエリを使用することをお勧めします。そのようなもの:
;WITH CategoriesTree(CategoryID, CategoryName, ParentName, CategoryLevel)
AS
(
SELECT
c.ID,
c.Name,
CAST('No Parent' AS VARCHAR(50)) AS ParentName,
0 AS CategoryLevel
FROM @Categories c
WHERE c.ParentID IS NULL
UNION ALL
SELECT c.ID, c.Name, p.CategoryName, p.CategoryLevel + 1
FROM CategoriesTree p
INNER JOIN @Categories c ON c.ParentID = p.CategoryID
)
SELECT *
FROM CategoriesTree
Where CategoryLevel = some id;
これにより、次のことが得られます。
CATEGORYID CATEGORYNAME PARENTNAME CATEGORYLEVEL
1 Root Cateogry No Parent 0
2 Sub Cateogry 1 Root Cateogry 1
3 Sub Cateogry 2 Root Cateogry 1
4 Sub Cateogry 3 Root Cateogry 1
8 sub Cateogry 1 of 3 Sub Cateogry 3 2
7 Sub Cateogry 1 of 2 Sub Cateogry 2 2
5 Sub Cateogry 1 of 1 Sub Cateogry 1 2
6 sub Cateogry 2 of 1 Sub Cateogry 1 2
これはどのように作動しますか?
このクエリを使用すると、選択するカテゴリのレベルを制御できます。たとえば、前のデモで使用したサンプル データのカテゴリ ツリーは次のとおりです。
1: RootCategory Category Level: 0
|
|
----------------------------
| | |
| | |
2: Sub1 3: Sub2 4: sub3 Category Level: 1
| | |
------------ | |
| | | |
| | | |
5: Sub1of1 6: Sub2of1 7: sub1of2 8: sub1of3 Category Level: 2
このクエリは、新しく生成された列を含むこのカテゴリ ツリーを提供しCategoryLevel
ます。
注意:デモで使用したサンプル データでは、親カテゴリは 1 つだけでした ( parentid
IS NULL のカテゴリ)。ただし、多くの親カテゴリがあった場合、クエリは正常に機能します。これは、次の CTE のアンカー クエリによるものです。
SELECT
c.ID,
c.Name,
CAST('No Parent' AS VARCHAR(50)) AS ParentName,
0 AS CategoryLevel
FROM @Categories c
WHERE c.ParentID IS NULL;
次に、生成された列を使用して、CategoryLevel
関心のあるレベルの子カテゴリのみを選択できます。
たとえば、ルート カテゴリの最初のサブカテゴリのサブカテゴリのみを選択する必要がある場合は、述語を使用してこれらのカテゴリを取得できますCategoryLevel = 2
。
;WITH CategoriesTree(CategoryID, CategoryName, ParentName, CategoryLevel)
AS
(
...
)
SELECT *
FROM CategoriesTree
WHERE CategoryLevel = 2;
これにより、次のことが得られます。
CATEGORYID CATEGORYNAME PARENTNAME CATEGORYLEVEL
8 sub Cateogry 1 of 3 Sub Cateogry 3 2
7 Sub Cateogry 1 of 2 Sub Cateogry 2 2
5 Sub Cateogry 1 of 1 Sub Cateogry 1 2
6 sub Cateogry 2 of 1 Sub Cateogry 1 2