ニュース用とコメント用の2つのテーブルがあり、ステータスが承認済みに設定されているコメントの数を取得したい。
SELECT ccc_news . * ,
count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, 0)) AS comments
FROM ccc_news
LEFT JOIN ccc_news_comments ON ccc_news_comments.news_id = ccc_news.news_id
WHERE `ccc_news`.`category` = 'news_layer2'
AND `ccc_news`.`status` = 'Active'
GROUP BY ccc_news.news_id
ORDER BY ccc_news.set_order ASC
LIMIT 20
しかし、このクエリの問題は、そのニュースに対応するコメントが存在するかどうかに関係なく、コメント列に対してフェッチされる最小値が1であることです。
どんな助けも高く評価されます。
sum()
の代わりにcount()
を使用します
以下を試してください:
SELECT ccc_news . * ,
SUM(if(ccc_news_comments.id = 'approved', 1, 0)) AS comments
FROM ccc_news
LEFT JOIN ccc_news_comments ON ccc_news_comments.news_id = ccc_news.news_id
WHERE `ccc_news`.`category` = 'news_layer2'
AND `ccc_news`.`status` = 'Active'
GROUP BY ccc_news.news_id
ORDER BY ccc_news.set_order ASC
LIMIT 20
より良い(とにかく短い):
SUM(ccc_news_comments.id = 'approved')
これは、Cの場合と同様に、MySQLのブール型がINT
0
および1
として表されるため機能します(ただし、DBシステム間で移植できない場合があります)。
他の回答で述べたCOALESCE()
に関しては、多くの言語APIは値を取得するときにNULL
を''
に自動的に変換します。たとえば、PHPのmysqli
インターフェイスを使用すると、COALESCE()
なしでクエリを実行しても安全です。
これは動作するはずです:
count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, NULL))
count()
は、値が存在するかどうかのみをチェックします。 0は既存の値と同等であるため、もう1つカウントしますが、NULLは存在しない値のようなものであるため、カウントされません。
次の行を置き換えます。
count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, 0)) AS comments
これで:
coalesce(sum(ccc_news_comments.id = 'approved'), 0) comments