FILTER
Cláusula agregada en Postgres 9.4+
Desde Postgres 9.4 hay una manera limpia y rápida (estándar SQL):
SELECT count(*) FILTER (WHERE score BETWEEN 0 AND 3) AS low
, count(*) FILTER (WHERE score BETWEEN 4 AND 7) AS mid
, count(*) FILTER (WHERE score BETWEEN 8 AND 10) AS high
, count(*) AS total
FROM foo;
total
se suma low
, mid
y high
, a no ser nulo o demás valores están involucrados.
Enlaces:
Lea también a continuación.
Postgres 9.3-
Hay un par de técnicas:
@Phil proporcionó la forma estándar con una CASE
declaración (excepto sum(1)
, que no es la forma estándar). Me gusta usar una forma más corta:
SELECT count(score BETWEEN 0 AND 3 OR NULL) AS low
, count(score BETWEEN 4 AND 6 OR NULL) AS mid
, count(score BETWEEN 7 AND 10 OR NULL) AS high
, count(*) AS total
FROM foo;
Si sus valores son como se definen en su pregunta (sólo 0
- 10
es posible), simplificar aún más:
SELECT count(score < 4 OR NULL) AS low
, count(score BETWEEN 4 AND 6 OR NULL) AS mid
, count(score > 6 OR NULL) AS high
, count(*) AS total
FROM foo;
Un poco más corto, apenas más rápido.
Diferencias sutiles
Hay sutiles diferencias cuando se compara con sum()
en la respuesta de Phil :
Lo más importante, por documentación :
Cabe señalar que, a excepción de count
, estas funciones devuelven un valor nulo cuando no se seleccionan filas. En particular, sum
de ninguna fila devuelve nulo, no cero como cabría esperar ...
count(*)
es la forma estándar y un poco más rápido que sum(1)
. De nuevo, se aplica nulo vs. 0.
Cualquiera de estas consultas (incluidas las de Phil) cuenta valores nulos para total
. Si eso no es deseable, use en su lugar:
count(score) AS total_not_null
SQL Fiddle en la página 9.3.
db <> violín aquí en la página 10.