@popov654
Специалист в области веб-технологий

Как сделать выборку «И» и «ИЛИ» на MySQL?

Добрый день,

Вопрос, должно быть, предельно простой, но я вдруг понял, что совсем не знаю на него ответа.

Как грамотно сделать выборку по тегам, используя только MySQL (желательно за один запрос и без хранимых процедур)?

Имеется три таблицы: таблица users, содержащая пользователей, таблица tags, содержащая id и названия тегов, и таблица user_tags, содержащая пары (user_id, tag_id). Задача: реализовать выборку всех пользователей, имеющих каждый из набора тегов (1, 2, ..., N), а также (опционально) имеющих хотя бы один из этих тегов.

И если во втором случае, наверное, может помочь DISTINCT (хотя у меня с ним были некоторые проблемы недавно), то с первым я вообще не представляю.

Предложите идеи, пожалуйста.
  • Вопрос задан
  • 301 просмотр
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Зависит от того, уникальна пара (user_id, tag_id) или нет.
Для уникальных всё просто
SELECT `u`.*
  FROM `users` AS `u`
  JOIN `user_tags` AS `ut` ON `ut`.`user_id` = `u`.`id`
    AND `ut`.`tag_id` IN (1, 2, ..., N)
  GROUP BY `u`.`id`
  HAVING COUNT(*) = N


Для неуникальных добавляется DISTINCT
SELECT `u`.*
  FROM `users` AS `u`
  JOIN `user_tags` AS `ut` ON `ut`.`user_id` = `u`.`id`
    AND `ut`.`tag_id` IN (1, 2, ..., N)
  GROUP BY `u`.`id`
  HAVING COUNT(DISTINCT `ut`.`tag_id`) = N
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@art_karetnikov
Лучший мой проект: Мобильный банк Сбербанка РФ.
Доброго. Я не буду давать вам готовый результат, а дам пищу к размышлению и один пример. Никакой Distinct не нужен, использовать его приходится в редких случаях. В остальном он говорит о том, что либо база спроектирована неверно, либо неверно написан запрос.

select * from tbl_user where id_user in (select id_user from tbl_user_tag);

Одна строка - и вот вам все пользователи, у которых есть хотя бы один признак.
Не менее просто делается выборка всех пользователей, у которых есть все признаки, но это для самостоятельного размышления. :) Удачи.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы