我有一棵樹,在樹中特定的節點可以出現在樹中的另一個節點。 (在我的例子中爲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