Рекурсивно выбирая топовую рекурсию в MySQL

0

У меня есть таблица, которая содержит чисто отношения между группами для приложения, которые могут иметь бесконечное количество подгрупп.

CREATE TABLE `shop_groups_group_rel` (
  `id_group` int(11) NOT NULL,
  `id_parent` int(11) NOT NULL,
  `type` enum('shop','group') NOT NULL
);

Тип "магазин" в основном означает его верхнюю часть.

Теперь мне нужно получить самую большую группу для ЛЮБОЙ группы, в которой я мог бы разбираться. Я изучил синтаксис MySQL LOOP, но не могу понять, как это смешивать с реальными запросами в базе данных.

Может ли кто-нибудь дать мне подсказку о том, как я могу рекурсивно выбрать родительскую группу, пока я не нахожусь в верхней группе?

Я знаю, что это может быть рискованным, потому что может быть бесконечное количество подгрупп, но на практике это никогда не будет более 2 или 3 подгрупп, и я могу легко наложить жесткий предел на это.

Спасибо

Теги:
loops
recursion

1 ответ

0
Лучший ответ

Если вы в порядке с жестким пределом, вы можете просто использовать соединения.

SELECT id_group,
COALESCE(p4.id_group, p3.id_group, p2.id_group, p1.id_group, g.id_group) 
  as top_id_group
FROM shop_groups_group_rel g
LEFT JOIN shop_groups_group_rel p1 ON p1.id_group = g.id_parent
LEFT JOIN shop_groups_group_rel p2 ON p2.id_group = p1.id_parent
LEFT JOIN shop_groups_group_rel p3 ON p3.id_group = p2.id_parent
LEFT JOIN shop_groups_group_rel p4 ON p4.id_group = p3.id_parent

Это явно не рекурсивно, поэтому вы не можете продолжать бесконечно, но вы можете добавить столько объединений, сколько разумно ожидаете в своем наборе данных. Это не очень быстро, но, по крайней мере, короткое замыкание в том, что как только вы достигнете верхнего родителя, он в основном пропустит остальные соединения.

  • 0
    Спасибо, Роб, это действительно то, что я могу сделать, даже не подумал об этом. Я все еще хотел бы знать, возможно ли сделать это в цикле. Но пока ваше решение поможет, никогда не должно быть более 3/4 подгрупп.
  • 0
    С MySQL вы можете выполнять «цикл» только в хранимой процедуре, поскольку он не поддерживает рекурсивные запросы (в отличие, например, от PostgreSQL или Firebird).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню