MySQL и PHP: поиск строк по полю в неопределенном количестве объединенных таблиц

Существует пример таблицы «main_table» с полями «ID», «some_data».

Есть сводная таблица agg с полями id, main_table_id, joinee_id.

А затем есть финальная таблица «joinee» с полями «id», «email».

Таблицы «main_table» и «joinee» находятся в отношениях «многие: многие» через «agg».

Я хотел бы иметь возможность искать все записи «main_table» по «электронной почте» от «joinee», не выполняя левое соединение, а затем группируя по «main_table». «id». Окончательный результат должен содержать список всех записей «main_table», по одному разу для каждой записи. Представьте себе это так: я хотел бы, чтобы «main_table» получил временное поле «участники», которое содержало бы все «электронные письма». записи «main_table», которые имеют какое-либо отношение к электронной почте, которую я ввел.

Это возможно?

Имейте в виду, что это только фрагмент гораздо большего запроса. 'main_table' уже объединена с 5 другими таблицами, и их поля уже используются в качестве фильтров. Дело в том, что я знаю, что в каждом из этих случаев может быть только одна объединенная таблица - с «присоединяемым» количество связанных записей варьируется.

Спасибо.


person Swader    schedule 17.12.2010    source источник


Ответы (1)


Объединение результатов строк в отдельные ячейки — это то, что реляционная модель не поддерживает, и большинство СУБД делают это исключительно плохо. Если бы вы пошли по этому пути, вам пришлось бы приложить немало усилий, например, использовать определяемые пользователем функции или нестандартные синтаксические функции для объединения значений.

Но если я вас правильно понимаю, ваша проблема заключается в том, что вам нужно найти записи в основной таблице, которые имеют желаемые записи в соответствующих строках электронной почты, и проблема в том, что существует отношение многие ко многим.

Как насчет этого:

  1. Напишите запрос, который находит интересующие вас email и inner join в таблице agg. Это даст вам соответствующие main_table_ids. Используйте distinct или group by для удаления двойников.
  2. Используйте запрос из 1 в качестве подзапроса и подключите его к запросу, который у вас есть сейчас, используя что-то вроде WHERE main_table.id IN (/* subquery */) или, альтернативно, inner join вашего существующего запроса к подзапросу из шага 1. Какой из них вы используете, зависит от обстоятельств. ; традиционно подзапросы медленнее соединений (при прочих равных условиях), но может быть и наоборот, в зависимости от вашей структуры и фактических данных. В некоторых старых СУБД буферизация результата подзапроса во временной таблице может оказаться полезной.
person tdammers    schedule 17.12.2010
comment
Спасибо за этот ответ, я проверю это и сообщу о своих выводах! - person Swader; 19.12.2010
comment
Хотя в итоге я полностью переписал запрос, это был правильный ответ для обработки текущего запроса. Благодарю вас! - person Swader; 23.04.2011