这是我的查询
$getPosts = mysql_query ('SELECT `posts`.*, COUNT(`comments`.`comment_id`)
FROM `posts`
LEFT JOIN `comments`
ON (`posts`.`post_id` = `comments`.`post_id`)
ORDER BY `posts`.`post_id` DESC')
or die(mysql_error());
然后循环它...
while ($post = mysql_fetch_row($getPosts))
{
echo $post[1] . ' ' . $post[4] . ' comments'; // example
}
一切正常,但仅适用于第一行。
现在,post_id 1有2条评论。 post_id 2在DB中没有注释。
我认为这是JOIN的工作原理,但我不明白。我认为LEFT JOIN只匹配左侧的内容(所以post_id)但是我尝试了INNER JOIN,OUTER JOIN等等。它不起作用
答案 0 :(得分:3)
您的COUNT()
聚合必须与GROUP BY
子句一起使用。 MySQL将在没有它的情况下返回结果,但它们不会是您期望的结果,因为它将不确定地返回一个相关行。
SELECT
`posts`.*,
`c`.`num_comments`
FROM
`posts`
/* join against a subquery which retrieves the number of comments per post_id */
LEFT JOIN (
SELECT `post_id`, COUNT(*) AS `num_comments`
FROM `comments`
GROUP BY `post_id`
) AS c ON (`posts`.`post_id` = `c`.`post_id`)
ORDER BY
`posts`.`post_id` DESC
MySQL可能允许您在没有子查询的情况下简化此操作,因为它不需要posts
中的每个列都列在GROUP BY
中,但不建议这样做,因为它赢了“无处不在。
/* MySQL only, not recommended */
SELECT
posts.*,
COUNT(comments.comment_id) AS num_comments
FROM
posts
LEFT JOIN comments ON posts.post_id = comments.post_id
GROUP BY posts.post_id
否则,您需要列出posts
中GROUP BY
的每一列,因为它们都是SELECT
。这将有效,因为联接只涉及一对多关系posts
到comments
。
在PHP中获取此行时,请使用别名num_comments
。建议使用mysql_fetch_assoc()
,并按名称而不是数字键访问列。
while ($post = mysql_fetch_assoc($getPosts))
{
echo $post['post_id'] . ' ' . $post['num_comments'] . ' comments';
}
从长远来看,如上面的评论中所述,考虑切换到更新的API,例如MySQLi或PDO,因为mysql_*()
扩展在下一个主要的PHP版本中面临弃用。