Mysql
 sql >> Database >  >> RDS >> Mysql

Come posso contare il numero di post che hanno un punteggio di voto zero o positivo?

Il modo più semplice per escludere i post i cui voti totali sono inferiori a zero è questo:

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)

La parte fondamentale qui è il having sum(value) < 0 che seleziona i post con voti netti negativi.

Dai commenti...

Per trovare utenti che hanno troppe risposte "cattive", probabilmente dovresti restituire quante risposte "buone" hanno fatto e decidere se nel complesso sono utenti "cattivi". Ad esempio, un utente che ha 5 risposte tutte errate è molto diverso da un utente con 1000 risposte di cui solo 5 sono errate, anche se entrambi hanno 5 risposte errate.

Prova questo:

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

Un paio di note su alcuni SQL Kung Fu lì dentro:

  • in MySQL, true è 1 e false è 0, quindi sommando una condizione, conti quante volte è vera. Questo è molto più semplice da codificare e più facile da leggere rispetto al goffo SUM(CASE ...) espressioni richieste da altri DB
  • effettuare un conteggio di SUM(.01) (che ho solo pensato a BTW) è il modo più breve per ottenere una percentuale, poiché non solo semplifica l'espressione, ma fa in modo che la risposta sia fluttuante in modo da evitare automaticamente l'arrotondamento aritmetico intero

Dichiarazione di non responsabilità:il codice potrebbe non essere compilato o non funzionare poiché è stato inserito nel mio telefono (ma c'è una ragionevole possibilità che funzioni)