我有一棵树,在树中特定的节点可以出现在树中的另一个节点。 (在我的例子中为2):SQL服务器跳过重复的关系(父子)在递归
1
/ \
2 3
/ \ \
4 5 6
\
2
/ \
4 5
注意2是重复的。第一下1,和第二下6. 我的递归是:
with cte (ParentId, ChildId, Field1, Field2) AS (
select BOM.ParentId, BOM.ChildId, BOM.Field1, BOM.Field2
from BillOfMaterials BOM
WHERE ParentId=x
UNION ALL
SELECT BOM.ParentId, BOM.ChildId, BOM.Field1, BOM.Field2 FROM BillOfMaterials BOM
JOIN cte on BOM.ParentId = cte.ChildId
)
select * from cte;
但问题是,在结果关系2-4和2-5是重复的(首先从关系1-2和第二从关系6 -2):
ParentId ChildId OtherFields
1 2
1 3
2 4 /*from 1-2*/
2 5 /*from 1-2*/
3 6
6 2
2 4 /*from 6-2*/
2 5 /*from 6-2*/
有什么办法可以跳过访问重复的关系吗?我没有看到任何逻辑为什么递归运行在已经在结果中的行上。它会更快。类似的东西:
with cte (ParentId, ChildId, Field1, Field2) AS (
select BOM.ParentId, BOM.ChildId, BOM.Field1, BOM.Field2
from BillOfMaterials BOM
WHERE ParentId=x
UNION ALL
SELECT BOM.ParentId, BOM.ChildId, BOM.Field1, BOM.Field2 FROM BillOfMaterials BOM
JOIN cte on BOM.ParentId = cte.ChildId
------> WHERE (select count(*) FROM SoFarCollectedResult WHERE ParentId=BOM.ParentId AND ChildId=BOM.ChildId) = 0
)
select * from cte;
我发现this thread,但它是8岁。
我使用SQL Server 2016
如果这是不可能的,那么我的问题是如何从最终结果中删除重复,但检查不同的只是在的ParentId和childID的列?
编辑:
预期的结果是:
ParentId ChildId OtherFields
1 2
1 3
2 4
2 5
3 6
6 2
如何区分6的1和2孩子的2个孩子? –
您的数据有瑕疵。你不能像那样把它们放在一起。你怎么知道一组2,4属于1,另一组属于6以下。如果你需要这种关系,你需要重建你的数据结构,因为作为一个标准的父母孩子,它不会工作。 –
这里有一个基本问题。树可以根据不同的方法遍历。没有真正意义上的“第一” - 谁来说哪个节点出现应该得到孩子。节点不能'实例化',然后通过他们的祖先进行区分,这使得它们不再是节点。 – Greenspark