如何使用MySQL Join查询每个主题的帖子数量?
嘿,这个问题我之前也踩过坑!你现在的问题核心是用了聚合函数但没加GROUP BY子句——MySQL在遇到COUNT这类聚合函数时,如果没有明确指定分组规则,就会把所有匹配的行当成一个大组来统计,所以自然只返回1条结果,统计的是所有帖子的总数(100条)。
正确的查询写法
要实现每个主题对应一条结果并统计帖子数,你需要加上GROUP BY,把数据按每个主题的唯一标识分组,同时如果要包含没有帖子的主题(如果有的话),最好把JOIN posts改成LEFT JOIN posts,避免这类主题被过滤掉:
SELECT t.id, t.name, u.user_name, DATE_FORMAT(t.created_at, '%M %e, %Y @ %h:%i %p') AS created_at, COUNT(p.id) AS reply_count FROM topics t JOIN users u ON t.user_id = u.id LEFT JOIN posts p ON p.topic_id = t.id GROUP BY t.id, t.name, u.user_name, t.created_at
关键细节解释
GROUP BY的作用:
这里我们按t.id(主题唯一ID)以及SELECT里所有非聚合的列(t.name、u.user_name、t.created_at)分组,告诉MySQL要为每个独立的主题单独统计帖子数量。严格模式下,SELECT中的非聚合列必须出现在GROUP BY中,避免出现不确定的结果。LEFT JOIN vs INNER JOIN:
如果你用原来的INNER JOIN posts,那没有对应帖子的主题会被直接排除;换成LEFT JOIN后,这类主题依然会出现在结果里,此时COUNT(p.id)会返回0(因为NULL值不会被COUNT统计),更符合“获取所有主题”的需求。为什么去掉COUNT会返回100行:
因为topics和posts的INNER JOIN会把每个主题的每条帖子都生成一条记录,20个主题×5条帖子=100行,这是JOIN后的原始数据行数,而加COUNT不加GROUP BY就会把这100行合并成一组统计总数。
按照这个写法,你的示例里会返回5条结果,每条对应一个主题,reply_count都是5,完全符合你的预期。
内容的提问来源于stack exchange,提问作者webizone

