Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.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查询_Sql_Sql Server_Recursion - Fatal编程技术网

用于识别的递归SQL查询

用于识别的递归SQL查询,sql,sql-server,recursion,Sql,Sql Server,Recursion,请参见下面的DDL: CREATE TABLE #MasterChild (MasterID decimal(25,0), ChildID decimal(25,0), ChildCreTime datetime) insert into #MasterChild values (150021032000000173536533,150021032000000173946207,'2016-04-22 13:27:30.483') insert into #MasterChild values

请参见下面的DDL:

CREATE TABLE #MasterChild (MasterID decimal(25,0), ChildID decimal(25,0), ChildCreTime datetime)
insert into #MasterChild values (150021032000000173536533,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173571072,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173573651,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173574917,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173582487,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173604342,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173931636,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173935066,150021032000000173946207,'2016-04-22 13:27:30.483')
insert into #MasterChild values (150021032000000173946207,150021032000000173952172,'2016-04-22 13:38:32.747')
insert into #MasterChild values (150021032000000173946207,150021032000000173954415,'2016-04-22 13:43:28.120')
insert into #MasterChild values (150021032000000173536533,150021032000000173954321,'2016-04-22 13:43:28.120')
insert into #MasterChild values (150021032000000173954321,150021032000000173954319,'2016-04-22 13:43:28.120')
下面是SQL语句:

with GetAllMerges
as
(
select masterid,childid from #MasterChild where masterid=150021032000000173571072 and childid=150021032000000173946207
union all
select #MasterChild.masterid,#MasterChild.childid from #MasterChild inner join GetAllMerges
on  
#MasterChild.childid=GetAllMerges.masterid 
or (#MasterChild.childid=GetAllMerges.childid and #MasterChild.masterid<>GetAllMerges.masterid)  
) 
select distinct masterid,childid from GetAllMerges

为什么会这样?我试图展示所有的孩子和主人是联系在一起的。例如,如果主控1链接到子控2,子控2链接到主控3,主控3链接到子控4,子控4链接到主控5,则人员1-5链接到所有子控和主控都是人员

正如您在这里尝试做的那样,递归CTE在出错之前有一个隐含的MAXRECURSION为100

您可以使用其中n是一个介于0和32767之间的数字来指定需要多少个递归,0基本上意味着运行到Competition为止,无论需要多长时间

我不建议你这样做

CTE的递归元素似乎没有终止符

不正确的递归CTE可能导致无限循环。对于 例如,如果递归成员查询定义返回相同的 对于父列和子列的值,将创建一个无限循环 创建。要防止无限循环,可以限制 通过使用 MAXRECURSION提示和选项中介于0和32767之间的值 INSERT、UPDATE、DELETE或SELECT语句的子句。这让 在解析代码之前,您可以控制语句的执行 正在创建循环的问题。服务器范围的默认值为100。 指定0时,不应用任何限制。只有一个MAXRECURSION值 可以为每个语句指定

重点补充


在更改MAXRECURSION设置之前,首先使用递归CTE的正确终止重新编写查询。

让我看看我是否理解您的方法:

您正在编写GetAllMerges来显示所需的数据,并且在函数内部递归地引用它


==>MasterChild.childid=GetAllMerges.masterid您应该在“内部联接”中切换childid和parentid,如下所示:

试试看

with GetAllMerges
as
(
select masterid,childid,1 AS RecLevel 
from #MasterChild 
where masterid=150021032000000173571072 and childid=150021032000000173946207
union all
select #MasterChild.masterid,#MasterChild.childid,GetAllMerges.RecLevel + 1 
from #MasterChild 
inner join GetAllMerges on #MasterChild.masterid=GetAllMerges.ChildID 
--or (#MasterChild.childid=GetAllMerges.childid and #MasterChild.masterid<>GetAllMerges.masterid)  
) 
select distinct masterid,childid from GetAllMerges

我评论了或是母子。。。远离,因为这会产生错误。。。请描述您试图实现的目标…

我不确定您为什么不使用while或do-while来逐步完成链接键?仅仅因为游标、循环和逐步方法是人们应该尽可能避免的事情?阅读有关RBAR、基于行和基于集的。。。递归CTE是遍历层次结构的一个很好的工具…@Shnugo虽然递归CTE显然是@Shaneis,但我已经看完了这篇文章-很好的一篇,如果您正在寻找一个计数器,但实际上与此无关。。。很明显,一个纯计数器,每一步加上+1,将是RBAR的最佳状态。但层次结构将在每个步骤中处理集合。如果一个parentID下有10个孩子,那么您将同时获得所有10个孩子,以此类推。。。在任何情况下,遍历由许多级联联接完成的经典层次结构都是一个繁重的过程。。。最后但并非最不重要的一点是:rCTE是一种特殊的SQL,因此索引、统计信息、、、的完全内联使用。@Shnugo递归CTE总是由RBAR处理。行被添加到,然后始终使用递归部分中的嵌套循环逐个处理。滚动您自己的迭代查询,以基于集合的方式一次处理一个级别,可以更高效,因为它允许使用哈希和合并联接。在大多数情况下,当递归CTE达到默认值100并因此中断时,这不是MAXRECURSION的问题,而是错误的遍历代码的问题:-另一个常见问题问题是,如果最后一个孩子以CTE循环运行的方式与家长相关…谢谢,但是,我还需要返回另一行的childid为mastered的孩子。因此,您注释的代码行需要取消注释。取消对该行的注释会导致原始问题。@w0051977如果我理解正确,则不应将其包含在递归CTE中。只需将连接添加到外部选择并包括这些行。您可以对此进行区分以避免重复,但我不相信我可以这样做,因为外部联接是递归的。例如,master 1链接到child 2,child 2链接到master 3,master 3链接到child 4等@w0051977如果您设置一个最小的测试场景,使用较短的ID,并且预期的输出适合您的数据,这将非常有帮助。在多个列和多个规则上构建层次结构是非常危险的。。。请使用“编辑”选项将这一点放入您的问题中,并提供一些您想要实现的细节…我的问题与此相同:
with GetAllMerges
as
(
select masterid,childid,1 AS RecLevel 
from #MasterChild 
where masterid=150021032000000173571072 and childid=150021032000000173946207
union all
select #MasterChild.masterid,#MasterChild.childid,GetAllMerges.RecLevel + 1 
from #MasterChild 
inner join GetAllMerges on #MasterChild.masterid=GetAllMerges.ChildID 
--or (#MasterChild.childid=GetAllMerges.childid and #MasterChild.masterid<>GetAllMerges.masterid)  
) 
select distinct masterid,childid from GetAllMerges