我有以下表结构:
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
我试图构建所有父子DIRECT和INDIRECT关系的结果集。所以假设我传递了ParentID = 2的参数,我希望结果集返回如下:
ParentId ChildId
-------------------
2 NULL
2 5
5 6
6 8
1 2
所以基本上这个显示所有可能的链接,可以在一个表中找到Parent ID = 2。 从Parent本身开始,它具有Child Id,然后与Child Id 6具有其他关系。此外,父ID 2也属于父ID 1,其也应显示在结果集中。请注意,关系可以扩展到 N个级别。我希望你明白我在这里想要达到的目标,如果没有,请告诉我,以便我能更清楚地解释。
到目前为止,我已经提出了下面的递归查询,但它会抛出一个错误,如下所示:
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
我已经在SQLFiddle here上提供了代码供您测试并尝试。
我真的很感激任何指导并帮助我实现理想结果的人。
答案 0 :(得分:4)
正如#Mikael Eriksson所说:"您的数据中有循环引用。 5是6的父级,6是5的父级。"
同样在递归部分中,您从上一步输出ParentId
,而不是仅从找到的行输出。{/ p>
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
我不明白的另一件事是你为什么会有ChildId
为空且ParentId
不为空的行。怎么可能呢?
这是否意味着您拥有其父项已知的未知项目?