Използване на IN:
SELECT p.*
FROM POSTS p
WHERE p.id IN (SELECT tg.post_id
FROM TAGGINGS tg
JOIN TAGS t ON t.id = tg.tag_id
WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
GROUP BY tg.post_id
HAVING COUNT(DISTINCT t.name) = 7)
Използване на JOIN
SELECT p.*
FROM POSTS p
JOIN (SELECT tg.post_id
FROM TAGGINGS tg
JOIN TAGS t ON t.id = tg.tag_id
WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
GROUP BY tg.post_id
HAVING COUNT(DISTINCT t.name) = 7) x ON x.post_id = p.id
Използване на EXISTS
SELECT p.*
FROM POSTS p
WHERE EXISTS (SELECT NULL
FROM TAGGINGS tg
JOIN TAGS t ON t.id = tg.tag_id
WHERE t.name IN ('Cheese','Wine','Paris','Frace','City','Scenic','Art')
AND tg.post_id = p.id
GROUP BY tg.post_id
HAVING COUNT(DISTINCT t.name) = 7)
Обяснение
Същността на нещата е, че COUNT(DISTINCT t.name)
трябва да съвпада с броя имена на маркери, за да се гарантира, че всички тези тагове са свързани с публикацията. Без DISTINCT съществува риск дубликатите на едно от имената да върнат 7 – така че ще имате фалшиво положително.
Ефективност
Повечето ще ви кажат, че JOIN е оптимален, но JOIN също рискуват да се дублират редове в набора от резултати. EXISTS би бил следващият ми избор – без дублиран риск и като цяло по-бързо изпълнение, но проверката на плана за обяснение в крайна сметка ще ви каже кое е най-доброто въз основа на вашата настройка и данни.