FILTERClausola 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;
totalaggiunge up low, mide 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 CASEdichiarazione 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- 10possibile), 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, sumdi 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.