У меня есть 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
Затем измените
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))
Моя версия проверяет, есть ли ровно два тега, связанные с данной записью, и никакой другой тег не связан с ней.
Вам просто нужны report_id, у которых нет других tag_id, вы можете добиться этого с помощью этого запроса:
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;
Вам просто нужно установить максимальное значение для исключения тех, у которых tag_id больше 2.
Не работает, тот же результат, имея count(1)= 2, делал то же самое, что и max(tag_id) < 3
@Irphan попробуйте сейчас, я забыл избавиться от того, где.
Да, на данный момент это возвращает правильный результат, но я вижу, что вы удалили where tag_id IN (1,2)
, и это важная часть. Если я изменю идентификаторы тегов на (2,3,4), как я получу результат только для (2,3,4)? . В основном мой поиск работает в соответствии с выбором тегов (выпадающий множественный выбор). Мне нужны данные в соответствии с выбором тегов.
Ну это другой вопрос. В любом случае это может быть достигнуто с помощью min( tag_id ) > 1 и max( tag_id ) < 5; Вы всегда можете использовать group_concat(tag_id) = '2,3,4';, если он упорядочен.
используя count (1) = 2, возвращая 5 строк, как на снимке экрана. Он должен возвращать только одну строку. Пожалуйста, проверьте скриншот