2

这是 SQL Server 问题

我有一组类别,它们的关系导致嵌套类别。

我想建立一条保持关系并建立 SEF url 的途径。这是我正在寻找的:

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---|Cat2---|6
根/Cat2---|3---|Cat2---|7
根/Cat1---|2---|Cat1---|4
根/Cat1---|2---|Cat1---|5

所以理想情况下,路径应该是这样的:

根/父/子(等等)!

4

1 回答 1

2

我不确定这是否是您正在寻找的东西,但我过去曾使用过递归 cte,因此这可能有助于构建项目路径。

注意:我已经包含了附加信息,例如每个项目的 Root Id 和 Level,以便您可以更改输出的顺序。

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

如果您希望将 Root 类别作为独立项目包含在结果集中,则可以将 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 回答