Извлекать записи, соответствующие точным значениям в списке (массиве)

#mysql

#mysql

Вопрос:

У меня есть 3 таблицы (отчет, теги, report_has_tags), и мне нужно выбрать запись, в которой есть только упомянутые теги.Ниже приведен запрос, который я использую

 SELECT r.*, rt.report_id, GROUP_CONCAT(rt.tag_id) as tag_ids, GROUP_CONCAT(t.tag_name) as tag_names 
FROM report r 
LEFT JOIN report_has_tag rt ON r.id=rt.report_id 
LEFT JOIN tags t ON rt.tag_id=t.id 
WHERE r.id in (select report_id from report_has_tag where tag_id IN (1,2) group by report_id having count(1) >1 ) 
GROUP BY r.id  
LIMIT 990 OFFSET 0
  

этот запрос возвращает все записи, содержащие теги 1,2, а также записи, содержащие тег 3,4. Мне просто нужны записи, которые имеют только тег 1, 2, а не 3 или другие теги.Пожалуйста, смотрите прикрепленное изображение https://ibb.co/Gdr6TDF

Ответ №1:

Вам просто нужны идентификаторы report_ids, у которых нет других идентификаторов tag_ids, вы можете достичь этого с помощью этого запроса:

 SELECT r.*, rt.report_id, GROUP_CONCAT(rt.tag_id) as tag_ids, GROUP_CONCAT(t.tag_name) as tag_names 
FROM report r 
LEFT JOIN report_has_tag rt ON r.id=rt.report_id 
LEFT JOIN tags t ON rt.tag_id=t.id 
WHERE r.id in (
    select report_id from report_has_tag group by report_id having count(1) >1 and max( tag_id ) < 3
) 
GROUP BY r.id  
LIMIT 990 OFFSET;
  

Вам просто нужно установить максимальное значение для исключения записей с идентификатором тега больше 2.

Комментарии:

1. Не работает, тот же результат, при count(1) = 2 выполнялось то же самое, что и max (tag_id ) < 3

2. @Irphan попробуйте сейчас, я забыл избавиться от where.

3. Да, на данный момент это возвращает правильный результат, но я вижу, что вы удалили where tag_id IN (1,2) и это важная часть. Если я изменю идентификаторы тегов на (2,3,4), как я получу результат только для (2,3,4) ? . В основном мой поиск работает в соответствии с выбором тегов (выпадающий множественный выбор). Мне нужны данные в соответствии с выбором тегов.

4. Ну, это другой вопрос. В любом случае, это может быть достигнуто с помощью min ( tag_id ) > 1 и max (tag_id ) < 5; Вы всегда можете использовать group_concat( tag_id ) = ‘2,3,4’;, если это упорядочено.

Ответ №2:

Затем измените

 having count(1) >1 
  

Для

 having count(1)=2 and not exists (select report_id from report_has_tag where tag_id not IN (1,2))
  

Моя версия проверяет, есть ли ровно два тега, связанных с данной записью, и никакой другой тег не связан с ней.

Комментарии:

1. используя значение count (1) = 2, возвращая 5 строк, как на скриншоте. Он должен возвращать только одну строку. Пожалуйста, проверьте скриншот