Проблема с запросом MySQL - сопоставление нескольких идентификаторов в объединенной таблице

0

У меня 3 таблицы:

действия, инструменты и, поскольку они разделяют: m отношение table Activities_tools.

Пользователи на моем сайте могут выбирать доступные инструменты на фильтре. Теперь я пытаюсь получить все действия, в которых доступны соответствующие инструменты.

Например, если я выбираю инструменты с идентификаторами 1 и 2 как доступные, я должен получать действия, требующие либо никаких инструментов, инструмента 1, инструмента 2, а также действий, требующих и того, и другого. Поэтому мероприятия, требующие применения других инструментов, должны быть исключены.

Мой запрос, который я пробовал до сих пор, выглядит следующим образом:

SELECT activities.*, GROUP_CONCAT(tool) AS tools

FROM activities

LEFT JOIN activities_tools ON activities_tools.activity = activities.id

WHERE ISNULL(tool) OR tool IN (1,2)

GROUP BY activities.id

(1,2) - это список идентификаторов, выбранных пользователем.

Часть ISNULL решает проблему получения действий, которые не имеют инструментов. Моя проблема теперь заключается в том, что, например, инструмент, имеющий инструменты 1 и 2 по мере необходимости, возвращается, когда доступен только один из них.

Как я могу проверить его сразу с несколькими значениями? Я пытался возиться с GROUP_CONCAT + HAVING + FIND_IN_SET и т.д., Но я не могу придумать решение.

Любая помощь приветствуется.

Теги:
mysqli

2 ответа

0

Попробовав еще несколько вещей и рассмотрев вход отсюда, я нашел свое решение :)

SELECT activities.*, GROUP_CONCAT(tool) AS tools
FROM activities
LEFT JOIN activities_tools ON activities_tools.activity = activities.id
GROUP BY activities.id
HAVING ISNULL(tool) OR FIND_IN_SET(1, tools) = 0 OR FIND_IN_SET(2, tools) = 0 etc.

Элементы "OR FIND_IN_SET (1, tools) = 1" являются идентификатором для исключения. Эта часть запроса генерируется динамически в PHP.

РЕДАКТИРОВАТЬ:

Прочитав супер классный трюк здесь:

MySQL find_in_set с несколькими поисковыми строками

Я скорректировал свое решение:

SELECT activities.*, GROUP_CONCAT(tool) AS tools
FROM activities
LEFT JOIN activities_tools ON activities_tools.activity = activities.id
GROUP BY activities.id
HAVING CONCAT(",", toys, ",") NOT REGEXP ",(x|y|z)," 

Где x, y и z равны id исключения. Таким образом, запрос намного короче.

0

Я думаю, вы можете использовать дополнительную проверку NOT IN:

SELECT activities.*, GROUP_CONCAT(tool) AS tools

FROM activities

LEFT JOIN activities_tools ON activities_tools.activity = activities.id

WHERE ISNULL(tool) OR (tool IN (1,2) AND activities.id NOT IN (SELECT activity FROM activities_tools WHERE tool NOT IN (1,2)))

GROUP BY activities.id

Ещё вопросы

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