Reputation: 4759
I have an SQL table like this
ID Name ParentID
------------------------------
1 Alex 0
2 John 0
3 Don 1
4 Philip 2
5 Shiva 2
6 San 3
7 Antony 6
8 Mathew 2
9 Cyril 8
10 Johan 9
-------------------------
Am looking for an out put like this
if I pass the ID 7,10
The out put table will be
ID Name Relation
------------------------------------
7 Antony Alex->Don->San->Antony
10 Johan John->Mathew->Cyril->Johan
How can I achieve that using CTE
Upvotes: 1
Views: 85
Reputation: 239764
This seems to do the trick. The key is to realise that we can build up the path in backwards fashion and stop when we no longer have a parent to locate:
DECLARE @t table (ID int not null, Name varchar(19) not null, ParentID int null)
insert into @t(ID,Name,ParentID) values
(1 ,'Alex',null),
(2 ,'John',null),
(3 ,'Don',1),
(4 ,'Philip',2),
(5 ,'Shiva',2),
(6 ,'San',3),
(7 ,'Antony',6),
(8 ,'Mathew',2),
(9 ,'Cyril',8),
(10,'Johan',9)
declare @search table (ID int not null)
insert into @search (ID) values (7),(10)
;With Paths as (
select s.ID as RootID,t.ID,t.ParentID,t.Name, CONVERT(varchar(max),t.Name) as Path
from
@search s
inner join
@t t
on
s.ID = t.ID
union all
select p.RootID,t.ID,t.ParentID,p.Name, t.Name + '->' + p.Path
from Paths p
inner join
@t t
on
p.ParentID = t.ID
)
select * from Paths where ParentID is null
Result:
RootID ID ParentID Name Path
----------- ----------- ----------- ------------------- ----------------------------
10 2 NULL Johan John->Mathew->Cyril->Johan
7 1 NULL Antony Alex->Don->San->Antony
(I've left in additional columns to help to show the final state. Querying the CTE without filtering may also be instructive)
I'd also caution that I wouldn't usually work with delimited strings if at all possible - it's not a great representation when SQL Server has types designed for working with multiple values.
Upvotes: 4
Reputation: 4192
Use Common table expression query :
CREATE TABLE #Table(ID INT,Name VARCHAR(MAX),ParentID INT)
INSERT INTO #Table(ID ,Name ,ParentID)
SELECT 1,'Alex',0 UNION ALL
SELECT 2,'John',0 UNION ALL
SELECT 3,'Don',1 UNION ALL
SELECT 4,'Philip',2 UNION ALL
SELECT 5,'Shiva',2 UNION ALL
SELECT 6,'San',3 UNION ALL
SELECT 7,'Antony',6 UNION ALL
SELECT 8,'Mathew',2 UNION ALL
SELECT 9,'Cyril',8 UNION ALL
SELECT 10,'Johan',9
;WITH Relationship ( _ID , _Name , _Relation , _ParentId) AS
(
SELECT ID , Name , Name , ID
FROM #Table
WHERE ParentID = 0
UNION ALL
SELECT ID , Name , _Relation + '->' + Name , _ParentId
FROM Relationship
JOIN #Table ON _ID = ParentID
)
SELECT _ID ID, _Name Name, _Relation Relation
FROM Relationship
WHERE _ID IN ( SELECT MAX(_ID) FROM Relationship GROUP BY _ParentId)
Upvotes: 1