Mit 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)
Einen JOIN verwenden
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
Verwendung von EXISTEN
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)
Erklärung
Der springende Punkt ist, dass COUNT(DISTINCT t.name)
muss mit der Anzahl der Tag-Namen übereinstimmen, um sicherzustellen, dass alle diese Tags mit dem Beitrag in Verbindung stehen. Ohne DISTINCT besteht die Gefahr, dass Duplikate eines der Namen eine Zählung von 7 zurückgeben könnten – Sie hätten also ein falsch positives Ergebnis.
Leistung
Die meisten werden Ihnen sagen, dass der JOIN optimal ist, aber JOINs riskieren auch, Zeilen in der Ergebnismenge zu duplizieren. EXISTS wäre meine nächste Wahl – kein doppeltes Risiko und im Allgemeinen schnellere Ausführung, aber die Überprüfung des Erklärungsplans wird Ihnen letztendlich sagen, was basierend auf Ihrer Einrichtung und Ihren Daten am besten ist.