1

これが私のクエリです

$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 などを試しましたが、機能しません。

4

1 に答える 1

3

集計は句COUNT()と共に使用する必要があります。GROUP BYMySQL はそれがなくても結果を返しますが、不確定に 1 つの関連する行を返すため、予期した結果にはなりません。

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

postsMySQL では、すべての列を にリストする必要がないため、おそらくサブクエリなしでこれを単純化できますが、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。結合には との 1 対多の関係のみが含まれるため、これは機能postscommentsます。

PHP でこの行を取得するときは、エイリアスを使用しnum_commentsます。mysql_fetch_assoc()を使用し、数値キーではなく名前で列にアクセスすることをお勧めします。

while ($post = mysql_fetch_assoc($getPosts))
{
    echo $post['post_id'] . ' ' . $post['num_comments'] . ' comments';
}

mysql_*()上記のコメントで述べたように、長期的には、拡張機能は次の主要な PHP バージョンで非推奨になるため、MySQLi や PDO などの新しい API に切り替えることを検討してください。

于 2013-03-10T02:22:57.183 に答える