#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 «. Ну, это была недостающая часть, и я долго ее пропускал! Большое вам спасибо (от нас двоих ;))