简体   繁体   English

SQL Server CTE父子递归

[英]Sql Server CTE Parent Child recursive

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 . 我正在尝试建立所有父子DIRECT和INDIRECT关系的结果集 So suppose I pass the parameter of ParentID = 2, I would like the result set to return exactly as below: 因此,假设我传递了ParentID = 2的参数,我希望结果集完全返回如下:

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. 因此,基本上,这显示了可以在一张表中找到的所有可能的链接 ,其中父ID =2。从父本身开始,它具有子ID,然后与子ID 6具有其他关系。父ID 2也属于父ID 1。这也应显示在结果集中。 Please note the relationship could expand to N number of levels . 请注意,该关系可以扩展到N个级别 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. 我在这里将代码放在SQLFiddle上,供您测试和尝试。

I would really appreciate anyone who guides and helps me in achieving my desired result. 我真的很感谢任何指导并帮助我实现理想结果的人。

As #Mikael Eriksson said: "You have a circular references in your data. 5 is parent to 6 and 6 is parent to 5." 正如#Mikael Eriksson所说:“您的数据中有一个循环引用。5是6的父级,而6是5的父级。”

Also in recursive part you output ParentId from previous step, not from just found rows. 同样在递归部分,您从上一步而不是仅从发现的行中输出ParentId

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. 我不明白的另一件事是,为什么会有这样的行,其中ChildId为null而ParentId不为null。 How can it be possible? 怎么可能呢?

Does it mean that you have unknown items whose parent is known? 这是否意味着您有未知的项,其父项是已知的?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM