FILTERKlauzula 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;
totaldodaje się low, midi 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 CASEinstrukcją (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- 10moż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 counttych funkcji zwracają wartość zerową, gdy nie są zaznaczone żadne wiersze. W szczególności sumbrak 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.