考虑以下简单的内容DAG:$ n( k! z$ z/ D: i+ D
1->2->3->4bar描述表(我在用)SQL Server 2005):parent_id child_id ... other edges,not connected to the subgraph above现在想象一下,我还有其他选择第一个和最后一个边缘的标准,即1-> 2和3-> 4。我想用这些来找到图表的其余部分。$ {4 {& x' [8 h }# C
我可以写递归CTE,如下所示(我用的是MSDN的术语):3 q# d O, a2 D0 c5 |6 o
with foo(parent_id,child_id) as (// anchor member that happens to select first and last edges:select parent_id,child_id from #bar where parent_id in (1,3)union all// recursive member:select #bar.* from #barjoin foo on #bar.parent_id = foo.child_id)select parent_id,child_id from foo但这导致边缘3-> 4两次选择:, r5 G6 i7 r+ r' C3 @, i/ O
parent_id child_id 333 4 ///22nd appearance!如何防止查询在描述的子图中重复?如果在查询的递归成员部分,我可以引用 到目前为止,递归CTE所有检索到的数据 7 e* J- Q2 V" m这个目的可以通过在递归成员中提供一个谓词来实现。但是,我认为我只能访问递归成员 最后一次迭代 返回的数据。4 f1 G: p6 e2 m" c# V
当有很多这样的重复时,它将无法很好地扩展。有没有办法防止这种不必要的额外交付?( ?& g3 ^( H; s" J* P1 i
请注意,我可以在句子的最后一行使用选择不同来实现所需的结果,但这似乎是 完成 所有(重复)递归 之后 应用,所以我觉得这不是理想的解决方案。+ h$ v, |7 T; J
Edit -hainstech建议通过添加谓词来消除递归在起始集中明确的路径(即递归)来停止递归where foo.child_idnot in (1,3)。这只对简单的情况有效,因为它很简单-所有重复集合中开始所有重复部分。它不能解决可能不存在的一般情况。例如,考虑将边线1->5 W* K- X' `! h- [" P1 l
4和4-> 5添加到上述集合中。即使使用建议的谓词,边缘4-> 5也会被捕获两次。, l6 g$ O" T/ K; h/ Y# x V