FILTER
Klauzula zagregowana w Postgres 9.4+
Od wersji Postgres 9.4 istnieje czysty i szybki (standardowy SQL) sposób:
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
dodaje się low
, mid
i high
, o ile nie są zaangażowane NULL lub inne wartości.
Spinki do mankietów:
Przeczytaj także poniżej.
Postgres 9.3-
Istnieje kilka technik:
@Phil podał standardowy sposób z CASE
instrukcją (z wyjątkiem sum(1)
, który nie jest standardowym sposobem). Lubię używać krótszej formy:
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;
Jeśli twoje wartości są zdefiniowane w pytaniu (tylko 0
- 10
możliwe), uprość dalej:
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;
Trochę krótszy, niewiele szybszy.
Subtelne różnice
Są subtelne różnice w porównaniu do sum()
w odpowiedzi Phila :
Co najważniejsze, według dokumentacji :
Należy zauważyć, że oprócz count
tych funkcji zwracają wartość zerową, gdy nie są zaznaczone żadne wiersze. W szczególności sum
brak wierszy zwraca zero, a nie zero, jak można się spodziewać ...
count(*)
to standardowy sposób i nieco szybszy niż sum(1)
. Ponownie obowiązuje wartość null vs. 0.
Każde z tych zapytań (w tym Phila) zlicza wartości null total
. Jeśli nie jest to pożądane, użyj zamiast tego:
count(score) AS total_not_null
Fiddle SQL w str. 9.3.
db <> skrzypce tutaj na stronie 10.