SQL:计算特定作者撰写的每篇文章的评论量
Posted
技术标签:
【中文标题】SQL:计算特定作者撰写的每篇文章的评论量【英文标题】:SQL: Count amount of comments for each post written by specific author 【发布时间】:2016-03-01 03:36:15 【问题描述】:我一直觉得我需要提高我的 SQL 知识,我正在努力,但仍然没有成功找到我的问题的答案。
我有 2 张桌子:Post
和 Comments
。
Post
表有一个 PK PostID, Username, Title, Content
。
Comments
表有一个 PK CommentID, FK PostID, Username, Content
。
Username
in PostID
是帖子作者的Username
,Comments
是评论者的username
。其他一切都应该是不言自明的。
主要挑战:我想选择该特定作者发表的所有帖子,并显示每个帖子的 cmets 数量,如果没有找到 cmets,则显示为零。多合一查询(如果可能?)
到目前为止,我最接近的是:
SELECT p.*, COUNT(*) as CommentAmount
FROM Posts p
LEFT OUTER JOIN Comments c
ON p.PostID = c.PostID
WHERE p.Username = 'author1'
GROUP BY c.PostID
它以某种方式工作,但如果该 PostID 不存在 cmets,则既不显示 Post 数据,也不显示 CommentAmount (0) - 这是有道理的,因为它找不到任何具有相同 c.PostID 的 p.PostID .如何让它也显示 0 CommentAmount?有可能吗?
这是我设置的示例 SQL Fiddle,因此您也可以进行测试!:http://sqlfiddle.com/#!9/f8941 更新:我在架构中犯了一个小错误......对不起,伙计们。在上面的小提琴中修复了^
UPDATE2:感谢大家的精彩回答!有趣的是,大多数解决方案如何在 SQL Fiddle 上完美运行,但似乎不适用于我在云上的数据库,使用 MySQL Workbench...我现在必须研究一下,谢谢大家!
【问题讨论】:
这是一个非常好的问题。我希望在 SO 上有更多这样的东西。准备小提琴工作,这是一个梦想。做得好 ! :) 【参考方案1】:您可以尝试以下方法。
SQL Fiddle
SELECT kk.*, IFNULL(_aa.total, 0) AS total_comments
FROM Posts AS kk
LEFT JOIN (
SELECT aa.PostID, COUNT(*) AS total
FROM Posts AS aa
LEFT JOIN Comments AS bb
ON aa.PostID = bb.PostID
GROUP BY bb.PostID
) AS _aa
ON kk.PostID = _aa.PostID
WHERE kk.Username = 'author1'
还要检查this 和this 关于GROUP BY
和SELECT
子句中的非聚合列。
【讨论】:
我不认为COUNT()
可以返回NULL
值。无需调用IFNULL()
函数来检查。
哦,是的,这是因为 LEFT JOIN(现在是凌晨 3 点,我不太清楚......)。
完全可以理解:)
看起来有点过于复杂,但如果它可以工作,我仍然会喜欢它,但它不适合我,对不起:(无论如何感谢您的回答!
+1 @KostasMitsarakis 是对的。正如我对已接受的答案所评论的那样,OP 的查询不是有效的 ANSI 兼容查询。不能选择非聚合列。 (所以,我认为我的答案是最好的;)【参考方案2】:
这个怎么样?
SELECT p.*,
(SELECT COUNT(*) FROM Comments WHERE PostID=p.PostID) AS num_comments
FROM Posts p
WHERE p.Username = 'author1'
【讨论】:
一直返回只有0评论量:( @ExacT 我误解了你的问题。更正。请注意,这个查询很简洁,没有使用GROUP BY
子句。
感谢您对性能和 ANSI 兼容性的解释,我对此一无所知。您重新制作的查询完美无缺,我相信您对GROUP BY
子句的看法。顺便说一句,我最终还是使用了您的解决方案。将此标记为已接受的答案。谢谢:)【参考方案3】:
SELECT p.*, (select COUNT(*) from comments c where c.PostID = p.PostID)
FROM Posts p
WHERE p.Username = 'author1'
【讨论】:
【参考方案4】:您唯一的问题是您的小提琴 XD 一切正常,您只是没有 author1 的帖子没有评论!看我加了一个http://sqlfiddle.com/#!9/9f2f6/1
【讨论】:
哇,你在作者中插入了“3”,而不是标题……我的错。感谢您的通知!我真正的解决方案不在小提琴上,所以我不得不转移,多么愚蠢的错误,但是我的查询无法解决问题:(【参考方案5】:您只需通过添加GROUP BY
并将COUNT()
聚合参数更改为指向Comments
来调整您的查询,以便在没有特定帖子的cmets 时启用存储值0
。
将Comments
中的哪一列放入COUNT()
并不重要,因为当不满足JOIN 条件时,每一列都有一个NULL
值。
SELECT p.*, COUNT(c.CommentID) AS CommentAmount
FROM Posts p
LEFT JOIN Comments c
ON p.PostID = c.PostID
WHERE p.username = 'author1'
GROUP BY 1,2,3,4
【讨论】:
谢谢!有用。会选择你作为接受的答案,但@Harsh 快了 2 分钟,所以:) 没问题,它对我来说已经足够好了,它对你有帮助:-)【参考方案6】:对您的查询进行一些小改动:
SELECT p.*, COUNT(c.CommentID) as CommentAmount
FROM Posts p
LEFT OUTER JOIN Comments c
ON p.PostID = c.PostID
WHERE p.Username = 'author1'
GROUP BY c.PostID
【讨论】:
谢谢!有用!与我最初的查询也几乎没有什么区别! 性能考虑)如果 100 个帖子有 100 个 cmets,则在内部填充 10,000 行并通过GROUP BY
减少 100 个输出。 SQL 语法)请注意,此查询(和 OP 的查询)虽然在 mysql 中运行,但它与 ANSI 不兼容,因此此查询返回语法错误。以上是关于SQL:计算特定作者撰写的每篇文章的评论量的主要内容,如果未能解决你的问题,请参考以下文章