FILTER
Clausola aggregata in Postgres 9.4+
Da Postgres 9.4 esiste un modo pulito e veloce (standard 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
aggiunge up low
, mid
e high
, a meno che non siano coinvolti NULL o di altri valori.
link:
Leggi anche sotto.
Postgres 9.3-
Esistono un paio di tecniche:
@Phil ha fornito una CASE
dichiarazione standard (ad eccezione di sum(1)
, che non è la modalità standard). Mi piace usare una forma più breve:
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 i tuoi valori sono quelli definiti nella tua domanda (solo 0
- 10
possibile), semplifica ulteriormente:
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 po 'più corto, a malapena più veloce.
Differenze sottili
Ci sono sottili differenze quando rispetto a sum()
in risposta di Phil :
Ancora più importante, per documentazione :
Va notato che, ad eccezione di count
, queste funzioni restituiscono un valore null quando non è selezionata alcuna riga. In particolare, sum
di nessuna riga restituisce null, non zero come ci si potrebbe aspettare, ...
count(*)
è il modo standard e un po 'più veloce di sum(1)
. Ancora una volta, si applica null vs. 0.
Ognuna di queste query (inclusa quella di Phil) conta valori nulli per total
. Se ciò non è desiderabile, utilizzare invece:
count(score) AS total_not_null
SQL Fiddle in pag. 9.3.
db <> violino qui a pag.10.