PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

In Redshift/Postgres, come contare le righe che soddisfano una condizione?

Innanzitutto, il problema che stai riscontrando qui è che quello che stai dicendo è "Se il voto è inferiore a 70, il valore di questa espressione del caso è count(rank). Altrimenti, il valore di questa espressione è count(rank) ." Quindi, in entrambi i casi, ottieni sempre lo stesso valore.

SELECT 
    CASE
        WHEN grade < 70 THEN COUNT(rank)
        ELSE COUNT(rank)
    END
FROM
   grades

count() conta solo valori non nulli, quindi in genere lo schema che vedrai per realizzare ciò che stai provando è questo:

SELECT 
    count(CASE WHEN grade < 70 THEN 1 END) as grade_less_than_70,
    count(CASE WHEN grade >= 70 and grade < 80 THEN 1 END) as grade_between_70_and_80
FROM
   grades

In questo modo l'espressione case valuterà solo 1 quando l'espressione di test è vera e sarà nulla in caso contrario. Quindi count() conterà solo le istanze non null, cioè quando l'espressione di test è vera, che dovrebbe darti ciò di cui hai bisogno.

Modifica:come nota a margine, nota che questo è esattamente lo stesso di come lo avevi originariamente scritto usando count(if(test, true-value, false-value)) , solo riscritto come count(case when test then true-value end) (e null è la posizione in false-value poiché un else non è stato fornito al caso).

Modifica:postgres 9.4 è stato rilasciato pochi mesi dopo questo scambio originale. Quella versione ha introdotto filtri aggregati, che possono rendere scenari come questo un po' più belli e chiari. Questa risposta ottiene ancora alcuni voti occasionali, quindi se ti sei imbattuto qui e stai utilizzando un postgres più recente (cioè 9.4+) potresti prendere in considerazione questa versione equivalente:

SELECT
    count(*) filter (where grade < 70) as grade_less_than_70,
    count(*) filter (where grade >= 70 and grade < 80) as grade_between_70_and_80
FROM
   grades