给定一个具有循环的有向图,如何仅使用标准SQL检测并列出循环? 输入=图形边缘和一个根节点,我们从中计算传递闭包。输出=循环中的节点列表。
答案 0 :(得分:0)
创建表#myEdge( ID INT IDENTITY(1,1)主键, NodeIDFrom INT, NodeIDTo INT )
插入#myEdge(NodeIDFrom,NodeIDTo)值(4,5),(5,6),(6,4);
DECLARE @rootNode AS整数= 4;
-从此根计算传递闭包。 Niveau列保留递归嵌套级别。
与cte_transitive_closure(rootNode,NodeFrom,NodeTo,Niveau) AS( 选择@ rootNode,NULL,@ rootNode,0
UNION ALL
SELECT rootNode, e.NodeIDFrom, e.NodeIDTo, Niveau+1
FROM cte_transitive_closure AS cte
JOIN #myEdge AS e ON cte.NodeTo=e.NodeIdFrom
WHERE Niveau < 99
) 选择 * INTO #transitive_closure FROM cte_transitive_closure;
SELECT * FROM #transitive_closure;
-从根开始作为已达到的目标,在跟踪中移回直到再次击中根。
与cte_cycle(NodeFrom,NodeTo,Cycle) AS( SELECT @ rootNode,NULL,0
UNION ALL
SELECT t.NodeFrom, t.NodeTo, 0
FROM cte_cycle AS cte
JOIN #transitive_closure AS t ON cte.NodeFrom = t.NodeTo
WHERE t.NodeFrom != @rootNode AND Cycle=0
UNION ALL
SELECT t.NodeFrom, t.NodeTo, 1
FROM cte_cycle AS cte
JOIN #transitive_closure AS t ON cte.NodeFrom = t.NodeTo
WHERE t.NodeFrom = @rootNode AND Cycle=0
) SELECT DISTINCT * FROM cte_cycle;
结果集:
NodeFrom-> NodeTo(循环)
4-> NULL(0)
4-> 5(1)
5-> 6(0)
6-> 4(0)