A maneira mais simples de excluir postagens cujo total de votos é menor que zero é assim:
SELECT count(1)
FROM qanda question
JOIN qanda answer ON question.Id = answer.related
WHERE answer.related IS NOT NULL
AND answer.user_id = 2
AND question.free IS NULL
AND question.id not in (
select post_id
from votes
group by post_id
having sum(value) < 0)
A parte chave aqui é o
having sum(value) < 0
que selecionam postagens com votos negativos líquidos. Dos comentários...
Para encontrar usuários que têm muitas respostas "ruins", você provavelmente deve retornar quantas respostas "boas" eles deram e decidir se, no geral, eles são um usuário "ruim". Por exemplo, um usuário que tem 5 respostas todas ruins é muito diferente de um usuário com 1000 respostas das quais apenas 5 são ruins, embora ambos tenham 5 respostas ruins.
Tente isto:
select
sum(score < 0) bad,
count(*) total,
sum(score < 0) / sum(.01) percent_bad
from (
SELECT coalesce(sum(value), 0) score
FROM qanda question
JOIN qanda answer ON question.Id = answer.related
LEFT JOIN votes ON votes.post_id = answer.id
WHERE answer.related IS NOT NULL
AND answer.user_id = 2
AND question.free IS NULL
AND answer.timestamp > subdate(now(), 365)
GROUP BY answer.id
) scores
Algumas notas sobre alguns SQL Kung Fu lá:
- no MySQL, true é 1 e false é 0, então somando uma condição, você conta quantas vezes ela é verdadeira. Isso é muito mais simples de codificar e mais fácil de ler do que o desajeitado
SUM(CASE ...)
expressões necessárias para outros bancos de dados - mergulhando uma contagem por
SUM(.01)
(que acabei de pensar em BTW) é a maneira mais breve de obter uma porcentagem, pois não apenas simplifica a expressão, mas ajusta a resposta para float, para que você evite automaticamente o arredondamento aritmético inteiro
Isenção de responsabilidade:o código pode não compilar ou funcionar como foi digitado no meu telefone (mas há uma chance razoável de funcionar)