Med 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)
Använda en 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
Använder 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)
Förklaring
Kärnan i saker är att COUNT(DISTINCT t.name)
måste matcha antalet taggnamn för att säkerställa att alla dessa taggar är relaterade till inlägget. Utan DISTINCT finns det en risk att dubbletter av ett av namnen kan returnera en räkning på 7 - så att du skulle få en falsk positiv.
Prestanda
De flesta kommer att säga att JOIN är optimal, men JOINs riskerar också att duplicera rader i resultatuppsättningen. FINNS skulle vara mitt nästa val - ingen dubbelrisk, och generellt snabbare utförande, men att kontrollera förklara planen kommer i slutändan att berätta vad som är bäst baserat på dina inställningar och dina data.