Select starting node ID in CTE
-
02-01-2021 - |
Frage
I have following table:
create table osoba(
id int primary key,
idNd int,
nazwim nvarchar(500),
)
Data looks like below:
id idNd nazwim 1 NULL grandpa 2 1 child1 3 1 child2 4 2 grandchild1child1 5 2 grandchild2child1 6 3 grandchild1child2 7 3 grandchild2child2
I've got following cte:
;WITH ret AS(
SELECT *
FROM osoba
--WHERE ID = 1
UNION ALL
SELECT o.*
FROM osoba o INNER JOIN
ret r ON o.idNd = r.ID)
Select * from ret returns all descendants for each node and starting node:
id idNd nazwim 1 NULL grandpa 2 1 child1 3 1 child2 4 2 grandchild1child1 5 2 grandchild2child1 6 3 grandchild1child2 7 3 grandchild2child2 6 3 grandchild1child2 7 3 grandchild2child2 4 2 grandchild1child1 5 2 grandchild2child1 2 1 child1 3 1 child2 6 3 grandchild1child2 7 3 grandchild2child2 4 2 grandchild1child1 5 2 grandchild2child1
How to retrieve information about starting node for each record? I would like to get result like that:
idStartingNode id idNd nazwim 1 1 NULL grandpa 1 2 1 child1 1 3 1 child2 1 4 2 grandchild1child1 1 5 2 grandchild2child1 1 6 3 grandchild1child2 1 7 3 grandchild2child2 3 6 3 grandchild1child2 3 7 3 grandchild2child2 2 4 2 grandchild1child1 2 5 2 grandchild2child1 2 2 1 child1 3 3 1 child2 6 6 3 grandchild1child2 7 7 3 grandchild2child2 4 4 2 grandchild1child1 5 5 2 grandchild2child1
Lösung
You add the column, in both parts of the recursive CTE.
Starting nodes have the ID
as startingNode id.
The descendants have as starting node id, the starting node id of their parent:
WITH ret AS
(
SELECT id AS idStartingNode, o.*
FROM osoba o
--WHERE ID = 1
UNION ALL
SELECT r.idStartingNode, o.*
FROM osoba o INNER JOIN
ret r ON o.idNd = r.ID
) ;
Andere Tipps
You also need level to get a meaningful report
declare @t table (id int primary key, idNd int, nazwim varchar(50));
insert @t values
(1, NULL, 'grandpa'),
(2, 1, 'child1'),
(3, 1, 'child2'),
(4, 2, 'grandchild1child1'),
(5, 2, 'grandchild2child1'),
(6, 3, 'grandchild1child2'),
(7, 3, 'grandchild2child2');
--select * from @t;
with cte as
( select id as ori, id, idNd, nazwim, 1 as level
from @t
union all
select c.ori, t.id, t.idNd, t.nazwim, level + 1
from cte c
join @t t
on t.idNd = c.id
)
select *
from cte
order by ori, level;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange