使用遞歸CTE的圖行走的痛苦問題。這是在圖中找到連接的子圖的問題。使用遞歸CTE的挑戰是防止不必要的遞歸 - 也就是無限循環在SQL Server中,這通常意味着將它們存儲在一個字符串中。
這個想法是獲得連接的所有節點對(以及節點與自身連接)的列表。然後,從連接節點列表中取最小值,並將其用作連接子圖的ID。
另一個想法是在節點的兩個方向上走圖。這確保了所有可能的節點被訪問。以下是完成此操作的查詢:
with fullt as (
select keyA, keyB
from t
union
select keyB, keyA
from t
),
CTE as (
select t.keyA, t.keyB, t.keyB as last, 1 as level,
','+cast(keyA as varchar(max))+','+cast(keyB as varchar(max))+',' as path
from fullt t
union all
select cte.keyA, cte.keyB,
(case when t.keyA = cte.last then t.keyB else t.keyA
end) as last,
1 + level,
cte.path+t.keyB+','
from fullt t join
CTE
on t.keyA = CTE.last or
t.keyB = cte.keyA
where cte.path not like '%,'+t.keyB+',%'
) -- select * from cte where 'g' in (keyA, keyB)
select t.keyA, t.keyB,
dense_rank() over (order by min(cte.Last)) as grp,
min(cte.Last)
from t join
CTE
on (t.keyA = CTE.keyA and t.keyB = cte.keyB) or
(t.keyA = CTE.keyB and t.keyB = cte.keyA)
where cte.path like '%,'+t.keyA+',%' or
cte.path like '%,'+t.keyB+',%'
group by t.id, t.keyA, t.keyB
order by t.id;
SQLFiddle是here。
更新:問題與無限遞歸 –
什麼是「無限遞歸」是什麼意思?對層次結構沒有理論限制?或者說層次結構在某些點上循環,以致在某些分支上幾乎沒有無子節點? - 編輯:看起來像後者,所以當你到達一個循環時你想要發生什麼? –
,因爲在某些情況下父母可能是孩子 –