这是 SQL Server 问题
我有一组类别,它们的关系导致嵌套类别。
我想建立一条保持关系的途径并建立 SEF 网址。这是我正在寻找的内容:
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
它给了我这样的东西:
root--------|1---|root---|2 root--------|1---|root---|3 root/Cat2---|3---|Cat2---|6 root/Cat2---|3---|Cat2---|7 root/Cat1---|2---|Cat1---|4 root/Cat1---|2---|Cat1---|5
所以理想的路径应该是这样的:
根/父/子(等等)!
最佳答案
我不确定这是否是您正在寻找的内容,但我过去曾使用过递归 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
关于在 SQL Server 中使用 With Union 的 SQL 构建路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10564367/