Подсчитайте количество голосов за сообщение

#mysql #sql #count

#mysql #sql #подсчитать

Вопрос:

В настоящее время мы застряли, пытаясь сделать простой (?) SQL-запрос.

У нас есть эти две таблицы:

 create table `post` (
    `id` integer primary key
)
create table `vote` (
    `id` integer primary key,
    `post_id` references `post`.`id`, // Well ok, it's a foreign key then...
    `value` int // 1 for a positive vote, or zero for a negative one
)
  

Мы пытаемся создать выборку, которая для каждого сообщения возвращала бы количество положительных и отрицательных голосов: SELECT post.id, <positive count>, <negative count> ...

Хотя это не сложно сделать с подвыборами, проблема начинается, когда мы пытаемся сделать это без подвыборов, но с join . Мы используем left outer join , и проблемы возникают, когда сообщение имеет только положительные или отрицательные голоса.

Хотя я понимаю проблему, я не могу понять, как это сделать только с join помощью, но я уверен, что это можно сделать без дополнительных выборов. Как бы вы это сделали?

(Ну, я не включил свой текущий запрос, чтобы он не направил вас в неправильном направлении …)

Ответ №1:

Предыдущий ответ был мусором, я забыл GROUP . Вот альтернатива, которая использует CASE , я ДУМАЮ, она обрабатывает NULL случай (поскольку WHEN предложение будет NULL ), но вам, возможно COALESCE , все-таки придется использовать…:

 SELECT post.id, SUM(CASE WHEN a.vote > 0 THEN 1 ELSE 0 END) up, SUM(CASE WHEN a.vote < 0 THEN 1 ELSE 0 END) down FROM post LEFT JOIN vote a ON (a.post_id = post.id) GROUP BY post.id
  

Предыдущий (неправильный) ответ:

Похоже, вам нужно использовать COALESCE для принудительного NULL обнуления a — следующее может работать, но не проверено:

 SELECT post.id, SUM(COALESCE(a.vote,0)), SUM(COALESCE(b.vote,0)) FROM post LEFT JOIN vote a ON (a.post_id = post.id AND value > 0) LEFT JOIN vote b ON (b.post_id = post.id AND value < 0)
  

Комментарии:

1. О, я не знал, что мы можем создавать «сложные» критерии объединения… Я всегда использовал простой «xx.yy_id = yy.id «. Ну, это была недостающая часть, и я долго ее пропускал! Большое вам спасибо (от нас двоих ;))