mysql-选择所有未标记的帖子隐藏
我有三个表,一个是posts,有id、title、content和timestamp列。另一个是标签,具有列id、tag和第三个posttags描述了POST和标签之间的一对多关系,具有列postid、tagid 现在,我想为什么不使用标签来节省时间,而不是在posts表中使用hidden、featured等列来描述一篇文章是应该对所有人可见还是应该显示在一个特殊的featured页面上。所以我决定所有有标签的帖子都会被选中,所有隐藏标签的帖子都会被隐藏 实现第一个是很容易的,因为我可以使用一个连接查询,在我的where子句中我可以提到where tag='featured',这将为我获得所有的特色帖子 但是举一个例子,如果我要使用这个查询,那么一个贴有标签的sports和hiddenmysql-选择所有未标记的帖子隐藏,mysql,sql,relational-database,Mysql,Sql,Relational Database,我有三个表,一个是posts,有id、title、content和timestamp列。另一个是标签,具有列id、tag和第三个posttags描述了POST和标签之间的一对多关系,具有列postid、tagid 现在,我想为什么不使用标签来节省时间,而不是在posts表中使用hidden、featured等列来描述一篇文章是应该对所有人可见还是应该显示在一个特殊的featured页面上。所以我决定所有有标签的帖子都会被选中,所有隐藏标签的帖子都会被隐藏 实现第一个是很容易的,因为我可以使用一个
SELECT * FROM posts
INNER JOIN posttags ON posttags.postid = posts.id
INNER JOIN tags ON posttags.tagid = tags.id
WHERE tag !='hidden'
但这仍然会返回标记为隐藏的帖子,因为它也标记了运动
PS我的问题与这个问题不同:因为它直接使用tagid,而我无法使用double join检查标记名而不是tagid来获得相同的结果。我还希望在同一查询中检索帖子的其他标记,这是不可能使用该问题答案中的方法的将标记按帖子分组,然后使用HAVING子句筛选不包含“隐藏”标记的组。由于MySQL的隐式类型转换和缺少真正的布尔类型,我们可以:
SELECT posts.*
FROM posts
JOIN posttags ON posttags.postid = posts.id
JOIN tags ON posttags.tagid = tags.id
GROUP BY posts.id
HAVING NOT SUM(tag='hidden')
按post对标记进行分组,然后使用HAVING子句筛选不包含“隐藏”标记的组。由于MySQL的隐式类型转换和缺少真正的布尔类型,我们可以:
SELECT posts.*
FROM posts
JOIN posttags ON posttags.postid = posts.id
JOIN tags ON posttags.tagid = tags.id
GROUP BY posts.id
HAVING NOT SUM(tag='hidden')
可以使用“不存在”子查询执行此操作:
SELECT p.*, t.* -- what columns you need
FROM posts AS p
INNER JOIN posttags AS pt
ON pt.postid = p.id
INNER JOIN tags AS t
ON pt.tagid = t.id
WHERE NOT EXISTS
( SELECT *
FROM posttags AS pt_no
INNER JOIN tags AS t_no
ON pt_no.tagid = t_no.id
WHERE t_no.tag = 'hidden'
AND pt_no.postid = p.id
) ;
或等效的左联接/为空:
这种类型的查询称为反半联接或只是反联接。在您的情况下,它稍微复杂一些,因为条件标记class='hidden'位于第三个表中。您可以使用NOT EXISTS子查询执行此操作:
SELECT p.*, t.* -- what columns you need
FROM posts AS p
INNER JOIN posttags AS pt
ON pt.postid = p.id
INNER JOIN tags AS t
ON pt.tagid = t.id
WHERE NOT EXISTS
( SELECT *
FROM posttags AS pt_no
INNER JOIN tags AS t_no
ON pt_no.tagid = t_no.id
WHERE t_no.tag = 'hidden'
AND pt_no.postid = p.id
) ;
或等效的左联接/为空:
这种类型的查询称为反半联接或只是反联接。在您的情况下,它稍微复杂一些,因为条件标记class='hidden'位于第三个表中。优雅且快速。你认为我也可以在不使用子查询的情况下,在同一查询中隐藏未标记帖子的标记吗?@PeeyushKushwaha:如果你愿意将标记作为分隔字符串获取,可以将GROUP_CONCATtag添加到选择列表中;否则,您将不得不使用子查询将posttags和tags表连接回上述结果。虽然您的答案对我这样的mysql noob更有意义,但ypercube的解决方案速度更快,因此我接受了。优雅且快速。你认为我也可以在不使用子查询的情况下,在同一查询中隐藏未标记帖子的标记吗?@PeeyushKushwaha:如果你愿意将标记作为分隔字符串获取,可以将GROUP_CONCATtag添加到选择列表中;否则,您必须使用子查询将posttags和tags表连接回上述结果。虽然您的答案对我这样的mysql noob更有意义,但ypercube的解决方案速度更快,因此我接受了这一点。它很快,但我不确定它是如何工作的,我需要对查询进行哪些更改才能检索标记?如果您需要帖子的所有标记,可以添加另一个join。无法执行此操作。您可以发布整个查询以获取所有标记吗?left join中有一些小问题/is null等效,mysql说:1054-on子句中的未知列'pt.postid'。第一个真的很快!它很快,但我不确定它是如何工作的,我需要对查询进行哪些更改才能检索标记?如果您需要帖子的所有标记,可以添加另一个连接。无法执行此操作。您可以发布整个查询以获取所有标记吗?left join中有一些小问题/is null等效,mysql说:1054-on子句中的未知列'pt.postid'。第一个真的很快!