我想知道实现这一目标的最有效方法,因为我最近在短时间内遇到了几个不同表现形式的问题。
作为一般例子,假设我们有一个包含Post对象,Tag对象的博客,并且它们形成了多对多的关系,因为很明显,每个帖子都有很多标签,而这些标签又可以与许多标签相关联讯息。
现在针对实际问题:如何最佳地查询其关联标记列表是否符合给定条件的所有帖子?
我的一个相当天真的搜索解决方案(“包含asd但不是fgh”)看起来或多或少是这样的:
SELECT * FROM Post INNER JOIN (
SELECT DISTINCT PostID FROM PostTags WHERE (
PostID IN (SELECT PostID FROM PostTags WHERE TagID = 'asd')
AND
PostID NOT IN (SELECT PostID FROM PostTags WHERE TagID = 'fgh')
)
) Results ON Post.ID = Result.PostID
优点是我可以或多或少地为我给出的任何逻辑表达式(AST)任意生成这个,缺点是我有一种唠叨的感觉,'n'嵌套查询不是最优雅的解决方案。 / p>
答案 0 :(得分:1)
使用子查询非常好;如果Post.ID
和PostTags.TagID
被编入索引或主键,它们将会很有效。
但是,您不需要这么多嵌套:
SELECT *
FROM Post
WHERE ID IN (SELECT PostID FROM PostTags WHERE TagID = 'asd')
AND ID NOT IN (SELECT PostID FROM PostTags WHERE TagID = 'fgh')
答案 1 :(得分:0)
select p.*
from posts
inner join posttags t1 on p.id = t1.post_id and t1.tagid = 'asd'
inner join posttags t2 on p.id = t2.post_id and t2.tagid in ('asd','xyz')
left join posttags t3 on p.id = t3.post_id and t3.tag_id = 'fgh'
where t3.post_id is null