1

I have following table structure:

create table Test(
  ParentId int,
  ChildId int
 )

insert into Test(ParentId, ChildId)
select 1, NULL
union
select 1, 2
union
select 1, 3
union
select 2, NULL
union
select 2, 5
union
select 5, 6
union 
select 6, 5
union 
select 6, 8

I'm trying to build a result set of all parent child DIRECT and INDIRECT relationships. So suppose I pass the parameter of ParentID = 2, I would like the result set to return exactly as below:

ParentId    ChildId
-------------------
2           NULL
2           5
5           6
6           8
1           2

So basically this shows all possible links that can be found in one table for Parent ID = 2. Starting off with Parent itself, it has Child Id which then has other relations with Child Id 6. Also the parent Id 2 falls under parent id 1 which should also show up in result set. Please note the relationship could expand to N number of levels. I hope you understand what I am trying to achieve here, if not then please let me know so that I can explain more clearly.

So far I have come up with below recursive query but it throws an error which is stated below:

DECLARE @ID INT = 2

;WITH MyCTE
AS (
    SELECT ParentId
        ,ChildId
    FROM Test
    WHERE ParentId = @ID

    UNION ALL

    SELECT T.ParentId
        ,Test.ChildId
    FROM Test
    INNER JOIN MyCTE T ON Test.ParentID = T.ChildId
    WHERE Test.ParentID IS NOT NULL
    )
SELECT *
FROM MyCTE

Error:
The statement terminated. The maximum recursion 100 has been exhausted before statement completion

I have put up the code on SQLFiddle here for you guys to test and try.

I would really appreciate anyone who guides and helps me in achieving my desired result.

Bat_Programmer
  • 6,717
  • 10
  • 56
  • 67
  • 1
    You have a circular references in your data. 5 is parent to 6 and 6 is parent to 5. That makes the recursion go round and round and ... Is this what your data actually look like? – Mikael Eriksson Apr 07 '14 at 10:48
  • And besides that circular reference - what's the conditions for getting (Parent, Child) 1, 2 in the end of the result? – Allan S. Hansen Apr 07 '14 at 10:52
  • @MikaelEriksson yes this is how data will look like as there many types of relationships that can exist between two persons. – Bat_Programmer Apr 08 '14 at 00:01
  • @AllanS.Hansen I have not setup the condition yet. I am looking for something generic that can return such a result set. – Bat_Programmer Apr 08 '14 at 00:08
  • Did you find an answer here? If @GriGrim didnt work for you, can you post your own solution? I'm having a similar problem. – crthompson Feb 18 '15 at 15:49

1 Answers1

4

As #Mikael Eriksson said: "You have a circular references in your data. 5 is parent to 6 and 6 is parent to 5."

Also in recursive part you output ParentId from previous step, not from just found rows.

declare @Test table (ParentId int, ChildId int)

insert into @Test (ParentId, ChildId)
select 1, null
union all
select 1, 2
union all
select 1, 3
union all
select 2, null
union all
select 2, 5
union all
select 5, 6
union all
--select 6, 5
--union all
select 6, 8

declare @id int = 2

;with MyCTE as (
    select ParentId, ChildId
    from @test
    where ParentId = @id

    union all

    select t2.ParentId, t2.ChildId
    from MyCTE t1
    inner join @Test t2 on t1.ChildId = t2.ParentId
)

select * from MyCTE

Another thing I didn't understand is why do you have such rows where ChildId is null and ParentId is not null. How can it be possible?

Does it mean that you have unknown items whose parent is known?

GriGrim
  • 2,891
  • 1
  • 19
  • 33