2

これはSQLServerの質問です

カテゴリのセットがあり、それらの関係はネストされたカテゴリになります。

関係を維持する経路を構築し、SEFURLを構築したいと思います。これが私が探しているものです:

Category table: 
ID, Name
1, Root
2, Cat1
3, Cat2
4, Cat1.1
5, Cat1.2
6, Cat2.1
7, Cat2,2

CategoryChild table: ParentCategoryID, ChildCategoryID
1, 2
1, 3
2, 4
2, 5
3, 6
3, 7

これは無制限のネストされた構造です。これが私がしていることです(私はそれが間違っていることを知っていますが、このようなものが欲しいです):

WITH  MenuItems
    AS (

        SELECT  

        CAST((ItemPath) AS VARCHAR(1000)) AS 'ItemPath',
        CategoryID, Category, ChildID
        FROM    #Mapping
        WHERE   CategoryID = 1
        UNION ALL
        SELECT  
                CAST((items.ItemPath + '-/' + MenuItem.Category) AS VARCHAR(1000)) AS 'ItemPath',
                MenuItem.CategoryID, MenuItem.Category, MenuItem.ChildID
        FROM     #Mapping AS MenuItem
                JOIN MenuItems AS items
                  ON items.ChildID = MenuItem.CategoryID 
       ) 
select * from MenuItems

それは私にこのようなものを与えます:

ルート--------|1---|ルート---|2
ルート--------|1---|ルート---|3
ルート/Cat2--- | 3 --- | Cat 2 --- | 6
ルート/Cat2--- | 3 --- | Cat 2 --- | 7
ルート/Cat1--- | 2 --- | Cat1 --- | 4
ルート/Cat1--- | 2 --- | Cat1 --- | 5

したがって、理想的には、パスは次のようになります。

ルート/親/子(など)!

4

1 に答える 1

2

これがあなたが探しているものであるかどうかはわかりませんが、過去に再帰cteで遊んだことがあるので、これはアイテムパスの構築に役立つ可能性があります。

注:出力の順序を変更できるように、各アイテムのルートIDやレベルなどの追加情報を含めました。

declare @Category table (Id int, Name varchar(10))
insert into @Category values (1, 'Root'),(2, 'Cat1'), (3, 'Cat2'), (4, 'Cat1.1'), (5, 'Cat1.2'), (6, 'Cat2.1'), (7, 'Cat2.2')

declare @CategoryChild table (ParentCategoryID int, ChildCategoryID int)
insert into @CategoryChild values (1, 2), (1, 3), (2, 4), (2, 5), (3, 6), (3, 7)

;with cte as 
(
    -- root part
    select 
        ccParent.ChildCategoryID Id,
        ccParent.ParentCategoryID ParentId,
        c.Name Name,
        CAST(parentCategory.Name + '/' + c.Name as varchar(1000)) as Path,
        ccParent.ChildCategoryID Root,
        0 as Level
    from
        @CategoryChild ccParent
    inner join
        @Category c on c.Id = ccParent.ChildCategoryID
    inner join
        @Category parentCategory on parentCategory.Id = ccParent.ParentCategoryID
    where
        ccParent.ParentCategoryID = 1

    union all

    -- recursive part
    select
        ccChild.ChildCategoryID Id,
        ccChild.ParentCategoryID ParentId,
        c.Name Name,
        CAST((cte.Path + '/' + c.Name) as varchar(1000)) as Path,
        cte.Root Root,
        cte.Level + 1 as Level
    from
        @CategoryChild ccChild
    inner join
        @Category c on c.Id = ccChild.ChildCategoryID
    inner join
        cte on cte.Id = ccChild.ParentCategoryID
)
select cte.Path 
from cte 
order by cte.Root, cte.Level

私の環境内で上記を実行すると、次の結果が得られます

Root/Cat1
Root/Cat1/Cat1.1
Root/Cat1/Cat1.2
Root/Cat2
Root/Cat2/Cat2.1
Root/Cat2/Cat2.2

結果セットにスタンドアロンアイテムとしてルートカテゴリを含めることを検討している場合は、cteの最初の部分を変更して、ルートアイテムの選択をハードコーディングできます。

;with cte as 
(
    -- root part
    select 
        c.Id Id,
        null ParentId,
        c.Name Name,
        CAST(c.Name as varchar(1000)) as Path,
        c.Id Root,
        0 as Level
    from
        @Category c
    where 
        c.Name = 'Root'

    union all

    ... same as before

フォローを与える

Root
Root/Cat1
Root/Cat1/Cat1.1
Root/Cat1/Cat1.2
Root/Cat2
Root/Cat2/Cat2.1
Root/Cat2/Cat2.2
于 2012-05-13T05:51:59.873 に答える