FILTER
Clause d' agrégation dans Postgres 9.4+
Depuis Postgres 9.4, il existe une méthode propre et rapide (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
additionne low
, mid
et high
, à moins que d' autres valeurs NULL ou sont impliquées.
Liens:
Lisez également ci-dessous.
Postgres 9.3-
Il existe quelques techniques:
@Phil a fourni la méthode standard avec une CASE
instruction (à l'exception de sum(1)
, qui n'est pas la méthode standard). J'aime utiliser un formulaire plus court:
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 vos valeurs sont telles que définies dans votre question (uniquement 0
- 10
possible), simplifiez davantage:
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 peu plus court, à peine plus rapide.
Différences subtiles
Il y a de subtiles différences par rapport à sum()
dans la réponse de Phil :
Plus important encore, par documentation :
Il convient de noter qu'à l'exception de count
, ces fonctions renvoient une valeur nulle lorsqu'aucune ligne n'est sélectionnée. En particulier, sum
aucune ligne ne renvoie null, pas zéro comme on pourrait s'y attendre, ...
count(*)
est la manière standard et un peu plus rapide que sum(1)
. Encore une fois, null vs 0 s'applique.
L'une ou l'autre de ces requêtes (y compris celle de Phil) compte des valeurs nulles pour total
. Si ce n'est pas souhaitable, utilisez plutôt:
count(score) AS total_not_null
SQL Fiddle en pg 9.3.
db <> violon ici en pg 10.