【问题标题】:Advanced SQLite query on many-to-many relationship多对多关系的高级 SQLite 查询
【发布时间】:2014-10-23 18:29:35
【问题描述】:

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

作为一般示例,假设我们有一个包含 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”个嵌套查询几乎不是最优雅的解决方案。

【问题讨论】:

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


    【解决方案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')
    

    【讨论】:

      【解决方案2】:
      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
      

      【讨论】:

      • 这有点难以扩展,但它绝对可以处理你可以扔给它的所有表达式。至少我看不到如何将“tag1 and (tag2 or tag3) and !tag4”翻译成那个。
      猜你喜欢
      • 2022-01-11
      • 2020-09-02
      • 2017-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 2018-11-02
      • 2015-10-26
      相关资源
      最近更新 更多