Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 递归查询循环_Sql Server_Tsql_Common Table Expression - Fatal编程技术网

Sql server 递归查询循环

Sql server 递归查询循环,sql-server,tsql,common-table-expression,Sql Server,Tsql,Common Table Expression,我有多对多表依赖关系,它有两列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].[De

我有多对多表依赖关系,它有两列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。所以我只需要处理一次这样的案件


谢谢你的帮助。

嗯。我想你的加入太多了。试试这个:

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 FIDLE;
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
以CTE为例( 选择SourceId,DependsOnId 来自[dbo]。[Dependency]
其中SourceId=@ParentID--您可以与我们共享一些示例输入数据吗?如果您的数据有周期,我很抱歉CTE对您的工作不是很好-您基本上需要在联合上执行一个
不同的
,我不确定CTE是否支持(尽管您可以尝试:))。临时桌子可能会更好。@Luaan谢谢你,这么多次尝试,什么都没有。结果我走错了路。我会试着用临时桌子,你们能把我推到正确的方向吗?因为我似乎无论如何都需要递归,但是你说CTE不是一个选项。主要的想法是你将有一个“无限”循环,它将不断地向你的临时表中添加唯一的行(一个简单的insert…select和临时表上的join应该可以工作-使用
level
列有助于跟踪头部,每个新循环只增加
level
,并尝试添加依赖于上一级别的行,只要它们不在临时表中),直到没有可以插入的行为止。这样,您将有一个充满唯一行的表。不幸的是,未成功(它只返回一级依赖项。但无论如何,谢谢您,您不能对CTE调用使用多个引用。因此您的func有错误)@IlyaLivshits…我不小心在答案中留下了一行代码。不管怎样,正如你所说,我有循环。所以,不是解决方案)