現在作業中の Web サイトのニュース ページを作成しようとしています。正しい MySQL クエリ (複数のクエリや num_rows ではなく、COUNT(id) と結合) を使用することにしました。正常に機能するはずの PDO ラッパーを使用していますが、MySQL CLI アプリケーションから直接実行すると、依然として失敗します。
基本的に、テーブルは 3 つあります。1 つはニュース、1 つはコメント、1 つはユーザーを保持します。ここでの目標は、ニュース投稿のタイトル、本文、作成者、日付をすべて表示する (後でページ付けします) ページを作成することです。2 番目のクエリを使用してユーザー名を取得したときは問題なく機能しましたが、その後、JOIN を使用することにしました。
では、何が問題なのでしょうか? 2 つの結合が必要です。1 つは著者のユーザー名を取得するもので、もう 1 つはコメントの数を取得するものです。著者のユーザー名だけを取得すると、すべて期待どおりに動作します。ニュース テーブルのすべての行 (2 つあります) が表示されます。ただし、コメント行にこの 2 番目の LEFT JOIN を追加すると、ニュースから 1 行しか取得できず (2 つあることを思い出してください)、COUNT(comments.id) は 2 を返します (投稿ごとにコメントがあるため、1 が表示されるはずです)。
何が間違っているのでしょうか? ニュース投稿が 2 つあり、それぞれにコメントが 1 つあるのに、ニュース投稿が 1 つしか表示されず、コメントが 2 つあると表示されるのはなぜですか?
SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id
また、もう 1 つ確認したいのですが、コメントへの左結合は、コメントの有無に関係なくすべての投稿を取得する正しい方法ですよね? それとも、右結合でしょうか? ああ、最後にもう 1 つ... comments.news_id = news.id を news.id = comments.news_id に切り替えると、結果は 0 になります。
ベストアンサー1
GROUP BY 句がありません:
SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id
GROUP BY news.id
左結合は正しいです。INNER または RIGHT JOIN を使用した場合、コメントのないニュース項目は取得されません。