#mysql #sql #hierarchical-data #recursive-query
#mysql #sql #иерархический-данные #рекурсивный запрос
Вопрос:
У меня есть таблица с информацией о переменных типах данных. Вызываемая inheritance
таблица со столбцами derived
и base
и следующими образцами данных;
derived | base
Double | Number
Int | Number
Int64 | Int
Number | Object
Как видно, могут быть некоторые базовые типы данных, которые также принадлежат производному столбцу. Но гарантируется отсутствие циклических зависимостей. Моя цель — получить выходные данные в виде двух столбцов, derived
, и base
где base
столбец является конечным корневым базовым элементом для соответствующего производного типа.
Например, Int64
имеет базовое значение as Int
. Я пытаюсь использовать рекурсию с версией MySQL> 8.0. Вот моя попытка;
WITH RECURSIVE hierarchy AS (
SELECT
derived,
base
FROM inheritance
UNION ALL
SELECT
inheritance.derived,
inheritance.base
FROM inheritance,hierarchy
WHERE inheritance.derived = hierarchy.base)
SELECT *
FROM hierarchy;
Кажется, что в моем завершении есть ошибка, поэтому я получаю следующую ошибку;
ERROR 3636 (HY000) at line 715: Recursive query aborted after 1001 iterations. Try increasing @@cte_max_recursion_depth to a larger value.
.
Пожалуйста, обратите внимание, что это только примерные данные, поэтому я пытаюсь написать общий рекурсивный запрос. Помощь / совет приветствуется.
Комментарии:
1. Я проверил то, что вы показали, но я не получаю никакой ошибки. Я использую MySQL 8.0.21. Какую точную версию вы используете?
2. Я бы предположил, что у вас есть данные, отличные от четырех строк примеров данных, которые вы показываете, и у вас может быть цикл в вашем наследовании.
3. Пожалуйста, предоставьте примеры данных и желаемые результаты.
Ответ №1:
Ваш запрос не должен генерировать такую ошибку; у вас, вероятно, есть циклическая зависимость в ваших данных, которую вам нужно будет сначала исправить.
Затем вы, похоже, хотите:
with recursive hierarchy as (
select derived, base, 1 lvl from inheritance
union all
select h.derived, i.base, h.lvl 1
from hierarchy h
inner join inheritance i on i.derived = h.base
)
select derived, base
from hierarchy h
where lvl = (select max(h1.lvl) from hierarchy h1 where h1.derived = h.derived)
Обоснование:
-
вы хотите отслеживать оригинал
derived
по мере продвижения вверх по иерархии -
рекурсивный запрос генерирует одну строку на промежуточный уровень; во внешнем запросе требуется дополнительная логика, чтобы сохранить только «самый глубокий» родительский элемент
Демонстрация в DB Fiddle как с вашим исходным запросом, так и с новым запросом
Комментарии:
1. @GMB ценю ваш ответ. Это имеет смысл. Мне было интересно, если я хочу изменить только для тех строк, где есть base
Number
, могу ли я просто фильтровать во внешнем запросе, а не брать самый глубокий уровень. Не могли бы вы любезно подтвердить?