使用 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)
使用连接
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 将是我的下一个选择 - 没有重复风险,并且通常执行速度更快,但检查解释计划最终会告诉您根据您的设置和数据什么是最好的。