Sandeep Thomas
Sandeep Thomas

Reputation: 4759

Listing all Parents of an items in a hierarchy table as delimitted string SQL

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

Answers (2)

Damien_The_Unbeliever
Damien_The_Unbeliever

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

Mansoor
Mansoor

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

Related Questions