Primero, el problema que tiene aquí es que lo que dice es "Si la calificación es inferior a 70, el valor de esta expresión de caso es contar (rango). De lo contrario, el valor de esta expresión es contar (rango) ." Entonces, en cualquier caso, siempre obtienes el mismo valor.
SELECT
CASE
WHEN grade < 70 THEN COUNT(rank)
ELSE COUNT(rank)
END
FROM
grades
count() solo cuenta valores no nulos, por lo que normalmente el patrón que verá para lograr lo que está intentando es 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
De esa manera, la expresión de caso solo se evaluará en 1 cuando la expresión de prueba sea verdadera y será nula de lo contrario. Luego, count() solo contará las instancias no nulas, es decir, cuando la expresión de prueba sea verdadera, lo que debería proporcionarle lo que necesita.
Editar:como nota al margen, tenga en cuenta que esto es exactamente igual a como lo había escrito originalmente usando count(if(test, true-value, false-value))
, solo se vuelve a escribir como count(case when test then true-value end)
(y nulo es el soporte en valor falso ya que un else
no se suministró al caso).
Editar:postgres 9.4 se lanzó unos meses después de este intercambio original. Esa versión introdujo filtros agregados, que pueden hacer que escenarios como este se vean un poco más agradables y claros. Esta respuesta aún recibe algunos votos a favor ocasionales, por lo que si se topó con aquí y está utilizando un postgres más nuevo (es decir, 9.4+), es posible que desee considerar esta versión 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