FILTER
Cláusula agregada no Postgres 9.4+
Desde o Postgres 9.4, existe uma maneira limpa e rápida (padrão 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
acrescenta-se low
, mid
e high
, a não ser nulo ou outros valores estão envolvidos.
Ligações:
Leia também abaixo.
Postgres 9.3-
Existem algumas técnicas:
A @Phil forneceu uma CASE
declaração da maneira padrão (exceto sum(1)
, que não é a maneira padrão). Eu gosto de usar um formulário mais curto:
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;
Se seus valores forem os definidos na sua pergunta (apenas 0
- 10
possível), simplifique ainda mais:
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;
Um pouco mais curto, um pouco mais rápido.
Diferenças sutis
Há diferenças sutis quando comparado com sum()
a resposta de Phil :
Mais importante, por documentação :
Deve-se observar que, exceto por count
, essas funções retornam um valor nulo quando nenhuma linha é selecionada. Em particular, sum
sem linhas retorna nulo, não zero, como se poderia esperar, ...
count(*)
é o caminho padrão e um pouco mais rápido que sum(1)
. Novamente, nulo vs. 0 se aplica.
Qualquer uma dessas consultas (incluindo as de Phil) conta valores nulos para total
. Se isso não for desejável, use:
count(score) AS total_not_null
SQL Fiddle na página 9.3.
db <> mexa aqui na página 10.