SQL Building Pathway utilisant avec Union dans SQL Server

C'est une question SQL Server

J'ai un set de catégories, et leur relation résulte en catégories nestedes.

Je veux build une voie en gardant la relation et build les URL du SEF. Voici ce que je cherche:

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 

C'est une structure nestede illimitée. Voici ce que je fais (je sais ce qui ne va pas mais je veux quelque chose comme ça):

 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 

Cela me donne quelque chose comme ça:

 racine -------- | 1 --- | racine --- | 2
 racine -------- | 1 --- | racine --- | 3
 racine / Cat2 --- | 3 --- | Cat2 --- | 6
 racine / Cat2 --- | 3 --- | Cat2 --- | 7
 racine / Cat1 --- | 2 --- | Cat1 --- | 4
 racine / Cat1 --- | 2 --- | Cat1 --- | 5

Donc, idéalement, le path devrait être comme ceci:

root / parent / enfant (et ainsi de suite)!

Je ne suis pas sûr si c'est ce que vous cherchez, mais j'ai joué avec des ctes récursives dans le passé et donc cela pourrait être utile dans la construction du path des éléments.

REMARQUE: j'ai inclus des informations supplémentaires telles que l'identifiant et le niveau racine pour chaque élément, afin que vous puissiez modifier l'ordre de la sortie.

 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 

Exécuter ce qui précède dans mon environnement donne les résultats suivants

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

Si vous souhaitez inclure la catégorie Racine dans votre jeu de résultats en tant qu'élément autonome, vous pouvez modifier la première partie du code pour coder en dur la sélection de l'élément racine.

 ;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 

Donner le suivant

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