Рекурсивный запрос в MySQL с использованием хранимой процедуры и CURSOR
Я расширяю нашу систему пользователей / групп, чтобы включить динамические группы, которые состоят из других членов групп. У меня три стола users
, groups
, а также relationships
,
Для простоты предположим, что пользователи содержат только одно поле user_id
и группы содержат только group_id
, relationships
использует три поля: user_id
, group_id
, related_group_id
представлять как пользователя в группу, так и отношения между группами.
Динамически заполненная групповая иерархия будет выглядеть примерно так:
пользователей A, B, C
принадлежат группе 1
и пользователи D, E, F
принадлежат к группе 2. Все они представлены в таблице отношений как (user_id
, group_id
):
A,1
B,1
C,1
D,2
E,2
F,2
Динамическая группа 3
будет иметь две группы, чтобы сгруппировать записи отношений (group_id
, related_group_id
):
3,1
3,2
Чтобы лучше проиллюстрировать мою проблему, давайте добавим динамическую группу 4
и включить его в группу 3
:
4,3
Собираем воедино то, что я узнал о MySQL CURSOR
я создал следующую хранимую процедуру fetch_inheritance_groups
:
DROP PROCEDURE IF EXISTS `fetch_inheritance_groups`;
CREATE PROCEDURE `fetch_inheritance_groups`(IN parent_id INT)
READS SQL DATA
BEGIN
DECLARE inherit_id char(32);
DECLARE eol BOOLEAN;
DECLARE inherit_cur CURSOR FOR SELECT r.Related_Group_ID FROM usr_relationships r WHERE r.Group_ID = parent_id AND r.Related_Group_ID IS NOT NULL;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET eol = TRUE;
OPEN inherit_cur;
inherited: LOOP
FETCH inherit_cur INTO inherit_id;
IF eol
THEN
CLOSE inherit_cur;
LEAVE inherited;
ELSE
CALL fetch_inheritance_groups(inherit_id);
END IF;
SELECT inherit_id;
END LOOP inherited;
END;
... который называется с...
CALL fetch_inheritance_groups(4);
... и возвращает ожидаемые результаты
3
2
1
Здесь начинается моя проблема, они возвращаются как три отдельных набора результатов, а не как три строки в одном наборе результатов, и, во-вторых, результаты предназначены для использования в запросе, например:
SELECT r.uer_id FROM relationships r WHERE r.group_id = 4 OR r.group_id IN (CALL fetch_inheritance_groups(4));
Итак, я надеюсь, что кто-то может ответить на три вопроса:
1. Должен ли я использовать CURSOR
здесь или есть альтернатива, которая получит такой же рекурсивный результат?
2. Как я могу получить результаты обратно в одном наборе результатов, чтобы его можно было использовать таким же образом, как и для подвыбора?
3. Как правильно использовать результаты CALL
потому что я не могу, по крайней мере, постараться заставить приведенный выше пример оператора SELECT работать? Я считаю, что это потому, что я не могу использовать CALL
встроенный, но я не уверен.