如何编写包含两个LEFT JOIN和两个COUNT的MySQL查询以获取帖子的评论数与点赞数
解决帖子评论数与点赞数统计的问题
嘿,我发现你当前的查询语句存在一个常见的陷阱——当你连续对comments和likes两张表做LEFT JOIN时,会产生笛卡尔积,导致统计出来的评论数和点赞数不准确。
问题原因解释
举个例子:假设某篇帖子有2条评论、3个点赞,经过两次LEFT JOIN后,这张帖子会生成2×3=6条重复记录。此时COUNT(comments.postId)和COUNT(likes.postId)都会统计成6,而不是真实的2和3——因为每条重复记录里的postId都存在,COUNT会把所有重复项都算进去。
解决方案1:子查询预统计(推荐,性能更优)
先分别统计每个帖子的评论数和点赞数,再关联到posts表,这样能避免笛卡尔积的问题:
SELECT p.id, COALESCE(c.num_of_comments, 0) AS num_of_comments, COALESCE(l.num_of_likes, 0) AS num_of_likes FROM posts p LEFT JOIN ( -- 预统计每个帖子的评论数 SELECT postId, COUNT(*) AS num_of_comments FROM comments GROUP BY postId ) c ON c.postId = p.id LEFT JOIN ( -- 预统计每个帖子的点赞数 SELECT postId, COUNT(*) AS num_of_likes FROM likes GROUP BY postId ) l ON l.postId = p.id;
这里用COALESCE函数是为了把没有评论/点赞的帖子对应的数量显示为0,而不是默认的NULL。
解决方案2:使用COUNT(DISTINCT)修正原查询
如果你的comments和likes表有唯一主键(比如id字段),可以在COUNT时加上DISTINCT来去重,这样也能得到正确结果:
SELECT posts.id, COUNT(DISTINCT comments.id) AS num_of_comments, COUNT(DISTINCT likes.id) AS num_of_likes FROM posts LEFT JOIN comments ON comments.postId = posts.id LEFT JOIN likes ON likes.postId = posts.id GROUP BY posts.id;
不过这种方式的性能不如子查询,因为两次JOIN会先生成大量重复记录,再通过DISTINCT去重,数据量大时会明显变慢。
总结
优先选择子查询预统计的方案,它逻辑清晰、性能更稳定,尤其是在数据量较大的场景下。
内容的提问来源于stack exchange,提问作者nikola
相关产品推荐
相关产品推荐

