SQL n: m Соединение наследования - PullRequest
4 голосов
/ 01 апреля 2012

Я хочу присоединиться к таблице, которая содержит отношения n: m между группами. (Группы определены в отдельной таблице). В этой таблице есть только записи, перечисляющие member_group_id и parent_group_id.

Учитывая эту структуру:

id(int) | member_group_id(int) | parent_group_id(int)

«Базовый» запрос выглядит так:

select p1.group_id, p2.group_id, p1.member_group_id, p2.member_group_id
from group_member_group as p1 
join group_member_group as p2 
on p2.member_group_id = p1.member_group_id

«Базовый» запрос корректно показывает все отношения (я проверял, делая это вручную.)

Проблема в том, что когда я пытаюсь применить предложение where к этому запросу, чтобы отфильтровать определенную группу как «точку происхождения» (первая группа, для которой мне нужны все родительские группы), он возвращает только ближайших родителей. Например, как это:

select p1.group_id, p2.group_id, p1.member_group_id, p2.member_group_id
from group_member_group as p1 
join group_member_group as p2 
on p2.member_group_id = p1.member_group_id
where p1.group_id = 1

Может кто-нибудь дать подсказку, как я могу это исправить? Или другой подход, чтобы понять это. (Полагаю, я всегда мог сделать это в исходном коде C ++ на стороне сервера, но мне пришлось бы перенести всю таблицу с высоким потенциалом роста на сервер приложений.)

UPDATE:

select p1.group_id, p2.group_id, p1.member_group_id, p2.member_group_id
from group_member_group as p1 
join group_member_group as p2 
on p2.group_id = p1.member_group_id

Ошибка ввода подтверждена. Теперь я не могу пройти первый уровень периода наследования. Спасибо, что отказали в указании на это.

ОБНОВЛЕНИЕ2: Ожидаемый результат

id | group_id | member_group_id
--------------------------------
1  |    1     |    2
2  |    2     |    3
3  |    3     |    4
4  |    4     |    5
5  |    5     |    6
6  |    6     |    7

ожидаемый результат:

идентификаторы

2
3
4
5
6
7

Ответы [ 2 ]

4 голосов
/ 01 апреля 2012
on p2.member_group_id = p1.member_group_id

это похоже на ошибку.

Может быть, вы хотели набрать

on p2.parent_group_id = p1.member_group_id

Возможно, вам следует поискать Модель вложенного набора для отношений родитель-потомок.

Гораздо проще делать подобные запросы в этой модели.

0 голосов
/ 02 апреля 2012

Я «разработал» другое «решение» для этого, если вы хотите назвать его так, поскольку технически это больше не единственный запрос.

Я написал процедуру MySQL, которая делает именно то, что я хочу.Он ищет всех родителей в одном узле, затем родителей следующего уровня и т. Д. И проверяет, найдены ли новые результаты (необходимо обнаруживать циклы в случае их появления, что должно быть предотвращено логикой приложения, но должно быть насо стороны сохранения я также ограничил максимальное расстояние до заданной суммы).

Но это действительно боль в заднице, и ее нужно модифицировать для каждой таблицы, на которой она должна использоваться.

Я думаю, что я буду придерживаться древовидной модели и просто ставить «учетные записи», если вы хотите назвать их так в нескольких группах.Это означает, что учетная запись имеет отношение 1: n с группами, а группа имеет отношение: 1 к родителям (в n группах есть 1 родитель, у этого родителя может быть другой родитель вплоть до «корневого» узла (классическое дерево)).

...