2017-01-09 4 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); 

Неожиданное поведение исходит из двух утверждений COUNT. Я ожидаю, что upvote_count быть эквивалентно

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

для каждого отдельного поста и так же для подсчета комментариев (которые я ожидаю, чтобы вернуть общее количество комментариев для каждого поста. Тем не менее, я получаю странные на первый взгляд случайных результатов этих запросов для этих двух полей. Может кто-нибудь мне помочь диагностировать проблему?

+0

Несвязанный, но: размещение круглых скобок вокруг столбцов в 'group by' бесполезно –

ответ

1

count() (и все другие агрегатные функции) игнорирует нулевые значения.

Однако COUNT(c) ссылается на полной строки («запись») из таблицы псевдоним c Но это всегда не null, даже если все столбцы этой записи равны нулю.

Вам необходимо изменить оба звонка count() и передать столбец из этой таблицы на него, например. count(u1.post_id) и count(c.post_id)

+0

Спасибо за подсказку, я только что исправил это. Я все равно получаю одинаковые странные результаты, но количество подсчетов, которое я получаю, на самом деле больше, чем количество строк во всей таблице upvotes/comments – user1023465

+1

@ user1023465: без подробных данных о примерах это сложно сказать, но объединение может увеличить количество строк в отношениях «один ко многим» или «многие ко многим». Возможно, вы хотите вместо этого использовать 'count (different u1.post_id)'. Лучший способ отладить это - запустить запрос ** без ** группы и посмотреть строки, которые возвращаются. Это скажет вам, почему вы получаете неожиданные цифры. –