PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

No Redshift/Postgres, como contar linhas que atendem a uma condição?


Primeiro, o problema que você está tendo aqui é que o que você está dizendo é "Se a nota for menor que 70, o valor desta expressão case é count(rank). Caso contrário, o valor desta expressão é count(rank) ." Então, em ambos os casos, você está sempre obtendo o mesmo valor.
SELECT 
    CASE
        WHEN grade < 70 THEN COUNT(rank)
        ELSE COUNT(rank)
    END
FROM
   grades

count() conta apenas valores não nulos, então normalmente o padrão que você verá para realizar o que está tentando é este:
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

Dessa forma, a expressão case só será avaliada como 1 quando a expressão de teste for verdadeira e será nula caso contrário. Então o count() contará apenas as instâncias não nulas, ou seja, quando a expressão de teste for verdadeira, o que deve fornecer o que você precisa.

Edit:Como uma observação lateral, observe que isso é exatamente o mesmo que você escreveu originalmente usando count(if(test, true-value, false-value)) , apenas reescrito como count(case when test then true-value end) (e null é o stand em false-value já que um else não foi fornecido ao caso).

Edit:o postgres 9.4 foi lançado alguns meses após essa troca original. Essa versão introduziu filtros agregados, que podem tornar cenários como esse um pouco mais bonitos e claros. Esta resposta ainda recebe alguns upvotes ocasionais, então se você se deparou aqui e está usando um postgres mais recente (ou seja, 9.4+), você pode querer considerar esta versão 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