ich kann zumindest helfen mit dem recusive CTE einer Adjazenzliste und eine materialisierte Pfad bauen:
Für diese Tabelle:
create table category (IDCategory int primary key,CategoryDesc varchar(32),Father int)
insert into category values
(1,'R1',0)
,(2,'ST',1)
,(3,'CT',1)
,(4,'SA',3)
,(5,'SA 10',2)
,(6,'SA 20',2)
,(7,'CA',2)
,(8,'SA',2)
,(9,'R2',0)
,(10,'ST',9)
eine rekursive CTE mit:
;with cte as (
-- anchor elements: where Father = 0
select
IDCategory
, categoryDesc
, Father
, parentName = convert(varchar(32),null)
, path = convert(varchar(128),categoryDesc)
from category
where Father = 0
-- recursion begins here
union all
select
c.IDCategory
, c.categoryDesc
, c.Father
, parentName = p.categoryDesc
, path = convert(varchar(128),p.path+' - '+c.categoryDesc)
from category c
inner join cte as p on c.Father= p.IDCategory
)
-- we select all the results
select cte.*
from cte
order by idCategory
Rückkehr:
+------------+--------------+--------+------------+-----------------+
| IDCategory | categoryDesc | Father | parentName | path |
+------------+--------------+--------+------------+-----------------+
| 1 | R1 | 0 | NULL | R1 |
| 2 | ST | 1 | R1 | R1 - ST |
| 3 | CT | 1 | R1 | R1 - CT |
| 4 | SA | 3 | CT | R1 - CT - SA |
| 5 | SA 10 | 2 | ST | R1 - ST - SA 10 |
| 6 | SA 20 | 2 | ST | R1 - ST - SA 20 |
| 7 | CA | 2 | ST | R1 - ST - CA |
| 8 | SA | 2 | ST | R1 - ST - SA |
| 9 | R2 | 0 | NULL | R2 |
| 10 | ST | 9 | R2 | R2 - ST |
+------------+--------------+--------+------------+-----------------+
Hinzufügen der auf den Anker des rekursiven CTE verbinden:
;with cte as (
-- anchor elements: where Father = 0
select
c.IDCategory
, c.categoryDesc
, c.Father
, parentName = convert(varchar(32),null)
, path = convert(varchar(128),c.categoryDesc)
, cd.First
, cd.Last
from category c
inner join CategoryDefinition cd
on c.IdCategory=cd.IdCategory
where Father = 0
-- recursion begins here
union all
select
c.IDCategory
, c.categoryDesc
, c.Father
, parentName = p.categoryDesc
, path = convert(varchar(128),p.path+' - '+c.categoryDesc)
, p.First
, p.Last
from category c
inner join cte as p on c.Father= p.IDCategory
)
select cte.*
from cte
--where IdCategory = 7
order by idCategory
rextester Demo: http://rextester.com/POSVP81190
kehrt:
+------------+--------------+--------+------------+-----------------+-------+------+
| IDCategory | categoryDesc | Father | parentName | path | First | Last |
+------------+--------------+--------+------------+-----------------+-------+------+
| 1 | R1 | 0 | NULL | R1 | 0 | 300 |
| 2 | ST | 1 | R1 | R1 - ST | 0 | 300 |
| 3 | CT | 1 | R1 | R1 - CT | 0 | 300 |
| 4 | SA | 3 | CT | R1 - CT - SA | 0 | 300 |
| 5 | SA 10 | 2 | ST | R1 - ST - SA 10 | 0 | 300 |
| 6 | SA 20 | 2 | ST | R1 - ST - SA 20 | 0 | 300 |
| 7 | CA | 2 | ST | R1 - ST - CA | 0 | 300 |
| 8 | SA | 2 | ST | R1 - ST - SA | 0 | 300 |
| 9 | R2 | 0 | NULL | R2 | 301 | 600 |
| 10 | ST | 9 | R2 | R2 - ST | 301 | 600 |
+------------+--------------+--------+------------+-----------------+-------+------+
Wollen Sie wirklich jede 'title' in seinem eigenen wollen Säule? Ein dynamischer Pivot einer rekursiven Cte scheint nur eine schlechte Idee zu sein. – SqlZim
@SqlZim was du sagst ist, nur Titel3 zu zeigen? Anstatt alle 3 Titel anzuzeigen? – fedee13
@SqlZim Ich (angeblich) brauche sie getrennt, weil die Verwendung muss jede Ebene auswählen. Erste Stufe 1 (R1, R2, R3 ....), nach Stufe 1 zeige ich die Optionen für Stufe 2 (ST oder CT), und entsprechend Stufe 2 zeige ich Stufe 3 (ST - SA, ST - CA 10, ST - CA 20 oder CT - CA, CT - SA). – fedee13