CTE递归查询循环

时间:2016-05-30 14:59:54

标签: sql-server tsql common-table-expression

我有很多表Dependency,它有两列SourceId和DependsOnId。我真的想以递归方式获得给定Id的所有家属。

现在我有下一个查询:

with Rec(SourceId, DependsOnId)
as (
 select SourceId, DependsOnId from [dbo].[Dependency]
 union all
 select Rec.SourceId, Rec.DependsOnId
 from [dbo].[Dependency] d
 join [dbo].[Dependency] dd
 on d.SourceId = dd.DependsOnId and d.DependsOnId = dd.SourceId 
 join Rec 
 on Rec.DependsOnId = d.SourceId

)
SELECT * FROM Rec
OPTION (MAXRECURSION 30000);

但它更喜欢无限循环。我理解为什么,这是因为镜像依赖性如1-> 2和2-> 1。所以我需要处理这种情况一次。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

嗯。我想,你有太多的联接。试试这个:

with Rec(SourceId, DependsOnId) as (
      select SourceId, DependsOnId
      from [dbo].[Dependency]
      union all
      select Rec.SourceId, d.DependsOnId
      from Rec join
           [dbo].[Dependency] d
           on Rec.DependsOnId = d.SourceId
    )
SELECT *
FROM Rec
OPTION (MAXRECURSION 30000);

子查询现在在循环时在一个额外的深度添加一个依赖项。

注意:如果您的数据中包含循环,则仍然可以进行无限递归。我建议您设置一个SQL小提琴,如果这对您不起作用。

答案 1 :(得分:0)

DECLARE @ParentID INT = 2;

WITH CTE AS(
        SELECT  SourceId, DependsOnId
        FROM    [dbo].[Dependency]
        WHERE   SourceId = @ParentID  --<-- Given Parent id 

        UNION ALL

        SELECT  t.SourceId, t.DependsOnId
        FROM    [dbo].[Dependency] t 
        INNER JOIN
                CTE c ON t.DependsOnId = c.SourceId
)
SELECT  *
FROM    CTE