PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Dans Redshift/Postgres, comment compter les lignes qui remplissent une condition ?

Tout d'abord, le problème que vous rencontrez ici est que ce que vous dites est "Si la note est inférieure à 70, la valeur de cette expression de cas est count(rank). Sinon, la valeur de cette expression est count(rank) ." Ainsi, dans les deux cas, vous obtenez toujours la même valeur.

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

count() ne compte que les valeurs non nulles, donc généralement le modèle que vous verrez pour accomplir ce que vous essayez est le suivant :

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

De cette façon, l'expression de cas ne sera évaluée à 1 que lorsque l'expression de test est vraie et sera nulle sinon. Ensuite, le count() ne comptera que les instances non nulles, c'est-à-dire lorsque l'expression de test est vraie, ce qui devrait vous donner ce dont vous avez besoin.

Edit :en remarque, notez que c'est exactement la même chose que la façon dont vous l'aviez écrit à l'origine en utilisant count(if(test, true-value, false-value)) , seulement réécrit comme count(case when test then true-value end) (et null est le stand en fausse-valeur depuis un else n'a pas été fourni au cas).

Edit :postgres 9.4 est sorti quelques mois après cet échange original. Cette version a introduit des filtres agrégés, ce qui peut rendre des scénarios comme celui-ci un peu plus agréables et plus clairs. Cette réponse reçoit encore quelques votes positifs occasionnels, donc si vous êtes tombé sur ici et que vous utilisez un postgres plus récent (c'est-à-dire 9.4+), vous voudrez peut-être envisager cette version équivalente :

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