【问题标题】:SQLITE3 query to return posts that do not have specific tagsSQLITE3 查询返回没有特定标签的帖子
【发布时间】:2013-11-20 06:37:11
【问题描述】:

考虑具有 POSTS 和 TAGS 的博客的典型场景。

我需要在给定的 TAGS 列表中找到所有没有 TAGS 的 POST。

这意味着没有任何列出的标签的帖子被选中。或者,反过来说,具有列表中任何标签的帖子都不会被选中。

我将如何构造一个合适的查询来做到这一点?

就本示例而言,查询应与具有 POSTS 表、TAGS 表和 POSTS_TAGS 表的 SQLITE3 数据库一起使用,以便查询

select p.title, t.name from posts p 
 inner join posts_tags pt on pt.post_id = p.id
 inner join tags t on t.id = pt.tag_id

返回加入其标签的所有帖子(具有多个标签的帖子被多次列出)。

我认为答案在于获取帖子的所有标签,因此我尝试使用group_concat 将其减少到每个带有所有标签的帖子的一行,但无法使其正常工作。这是我尝试过的:

select p.title, t.name, group_concat(t.name) from posts p
 inner join posts_tags pt on pt.post_id = p.id 
 inner join tags t on t.id = pt.tag_id;

但是这会返回一行作为所有帖子的所有标签的最后一篇帖子。下一步是排除标记包含任何已排除标记的行。

我会继续尝试解决这个问题,但如果有人能提出一个查询来返回所有没有任何指定标签的帖子,那将非常有帮助。

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    您可以使用correlated subquery 查找帖子的所有标签,然后只需使用 NOT EXISTS 检查是否未找到标签:

    SELECT *
    FROM posts
    WHERE NOT EXISTS (SELECT 1
                      FROM posts_tags
                      WHERE posts_tags.post_id = posts.id
                        AND posts_tags.tag_id IN (1, 22, 333, ...))
    

    也可以使用outer join 并检查连接与任何标记记录不匹配的位置:

    SELECT posts.*
    FROM posts
    LEFT JOIN posts_tags ON  posts.id = posts_tags.post_id
                         AND posts_tags.tag_id IN (1, 22, 333, ...)
    WHERE posts_tags.tag_id IS NULL
    

    ...但这不是很有效,因为它需要数据库在过滤掉所有连接记录之前构造它们。

    【讨论】:

    • 谢谢,这为我指明了正确的方向。我在这里发布之前尝试了一个子查询,但是已经很晚了,而且我做得不太对。在这个答案的指导下,我能够重新审视我所做的事情,它现在做了我需要的事情——这样你就可以 CL。
    猜你喜欢
    • 2020-12-27
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 2013-11-01
    • 1970-01-01
    • 2022-01-13
    相关资源
    最近更新 更多