Обнаруживать циклы на графике в SQL, используя рекурсивное общее табличное выражение

Учитывая ориентированный граф с циклом, как вы обнаруживаете и перечисляете цикл, используя только стандартный SQL? input = ребра графа и корневой узел, из которого мы вычисляем транзитивное замыкание. Выход = список узлов в цикле.

Вы не задали вопрос здесь. Что ты спрашиваешь?

Larnu 21.06.2019 12:14

Какой набор результатов вы ищете? Образцы данных и желаемые результаты помогают.

Gordon Linoff 21.06.2019 12:33

вводом является таблица с именем #myEdge, представляющая данные графика, и @rootNode. Выход - это набор результатов, показывающий цикл

Ludovic Aubert 21.06.2019 13:58
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
3
166
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
CREATE TABLE #myEdge (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    NodeIDFrom INT,
    NodeIDTo INT
)

INSERT INTO #myEdge(NodeIDFrom, NodeIDTo) VALUES (4, 5),(5, 6),(6, 4);

DECLARE @rootNode AS integer = 4;

--compute the transitive closure from this root. column Niveau holds the recursion nesting level.

WITH cte_transitive_closure(rootNode, NodeFrom, NodeTo, Niveau)
AS (
    SELECT @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
)
SELECT *
INTO #transitive_closure
FROM cte_transitive_closure;

SELECT * FROM #transitive_closure;

--starting from root as a reached target, move back in the trace until the root is hit again.

WITH 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;


result set:

NodeFrom    -> NodeTo   (Cycle)

4   -> NULL (0)

4   -> 5    (1)

5   -> 6    (0)

6   -> 4    (0)

пожалуйста, обновите исходный вопрос с этим запросом

Squirrel 21.06.2019 12:20

Другие вопросы по теме