MySQL查询(使用JOIN)仅检索第一行

时间:2013-03-10 02:20:29

标签: php mysql join

这是我的查询

$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等等。它不起作用

1 个答案:

答案 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

否则,您需要列出postsGROUP BY的每一列,因为它们都是SELECT。这将有效,因为联接只涉及一对多关系postscomments

在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版本中面临弃用。