高级SQLite查询多对多关系

时间:2014-10-23 09:01:16

标签: sqlite many-to-many boolean-logic

我想知道实现这一目标的最有效方法,因为我最近在短时间内遇到了几个不同表现形式的问题。

作为一般例子,假设我们有一个包含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>

2 个答案:

答案 0 :(得分:1)

使用子查询非常好;如果Post.IDPostTags.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