Рекурсивная выборка из MariaDB всех связей
Мой запрос выполняет бесконечный рекурсивный поиск, я понимаю проблему но не вижу решения.
Моя таблица:
CREATE TABLE `mytable` (
`a` int(11) NOT NULL,
`b` int(11) NOT NULL,
`x` int(11) NOT NULL,
KEY `a` (`a`,`b`,`x`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `mytable` (`a`, `b`, `x`) VALUES
(1, 1, 1),
(2, 1, 1),
(2, 2, 5),
(3, 2, 2),
(3, 2, 4),
(3, 3, 2),
(4, 3, 2),
(4, 3, 3),
(5, 3, 4),
(6, 3, 4);
Моя задача получить все связи строк используя то поле X то поля A и B.
Сначала находим все записи с условием a = 4 b = 3 затем ищем все записи совпадающие с X и у найденных записей ищем уже с новыми условиями и так рекурсивно.
Я использовал следующий запрос, но получаю бесконечную рекурсию и понимаю почему так происходит, но не понимаю что необходимо добавить дабы остановить бесконечную рекурсию. Я пробовал использовать LIMIT но это не даёт никакого эффекта, полагаю я копаю не в ту сторону.
WITH RECURSIVE cte (a, b, x) as (
SELECT a, b, x
FROM mytable
WHERE a = 4 AND b = 3
UNION ALL
SELECT m.a, m.b, m.x
FROM mytable m
INNER JOIN cte ON m.x = cte.x
)
SELECT * FROM cte;
Ответы (1 шт):
Для исключения бесконечной рекурсии следует использовать UNION DISTINCT.
Поскольку требуется на нечётном шаге связывать по x, а на чётном по (a, b) - используются два рекурсивных блока.
WITH RECURSIVE
cte AS (
SELECT a, b, x FROM test WHERE (a, b) = (4, 3)
UNION
SELECT test.a, test.b, x FROM test JOIN cte USING (x)
UNION
SELECT a, b, test.x FROM test JOIN cte USING (a, b)
)
SELECT * FROM cte ORDER BY a, b, x
PS. Есть такая шутка: "Чтобы понять, как выполняется рекурсия, надо понять, как выполняется рекурсия". Однако в данном случае и в приведённой формулировке это не шутка, а чёткая и совершенно однозначная инструкция.
