2017-01-09 13 views
0

私はSQLクエリをデバッグするのに少し問題があり、本当に助けに感謝します。ここでPostgres LEFT JOIN and COUNT

はクエリです:

SELECT p.id, p.type, p.submission_id, 
    p.title, p.description, p.date, extract('epoch' FROM p.time) AS time, 
    podcasts.image_url, podcasts.title AS podcast_title, 
    COUNT(u1) as upvote_count, u2.id as upvote_id, 
    episodes.mp3_url, episodes.duration, 
    COUNT(c) as comment_count 
FROM posts AS p LEFT JOIN upvotes AS u1 ON p.id=u1.post_id AND u1.comment_id=-1 
LEFT JOIN upvotes AS u2 ON p.id=u2.post_id AND u2.user_id=$1 AND u2.comment_id=-1 
LEFT JOIN episodes ON p.submission_id = episodes.id 
LEFT JOIN podcasts ON episodes.podcast_id=podcasts.id 
LEFT JOIN comments AS c ON c.post_id=p.id 
WHERE p.type='podcast' AND p.time IS NOT NULL 
GROUP BY(p.id, u2.id, podcasts.image_url, episodes.mp3_url, episodes.duration, podcasts.title); 

予期しない動作が2つのCOUNT文から来ています。私は、各記事のコメントの総数を返すことを期待している(upvote_countコメント数のため、個々のポストと同じため

SELECT COUNT(*) FROM upvotes WHERE upvotes.post_id = (individual post id); 

と同等であることを期待しています。しかし、私はこれらのクエリからの奇妙な一見ランダムな結果を取得していますこれらの二つのフィールドのための。誰も私は、問題の診断に役立つことはできますか?

+0

関連性はありませんが、 'group by'の列を囲む括弧は無駄です –

答えて

1

count()(および他のすべての集計関数)をnull値を無視します。

しかし、COUNT(c)がテーブルから完全行(「記録」)を参照しエイリアスcしかし、そのレコードのすべての列がnullであっても、常にnullではないです。

count()の両方の呼び出しを変更し、の列をそのテーブルに渡す必要があります。 count(u1.post_id)count(c.post_id)

+0

チップをありがとう、私はそれを修正しました。私はまだ同じ奇妙な結果を得ていますが、カウントは実際にupvotes/commentsテーブル全体の行数よりも大きくなっています – user1023465

+1

@ user1023465:詳細なサンプルデータがなくても、 1対多または多対多の関係で行の数が増える可能性があります。たぶんあなたは 'count(distinct u1.post_id)'を代わりに使いたいかもしれません。これをデバッグする最善の方法は、** by group byを使わずに**クエリを実行し、返される行を調べることです。それは、あなたが予期せぬ数字を得る理由を教えてくれるでしょう。 –