Совокупное FILTER
предложение в Postgres 9.4+
Начиная с Postgres 9.4, существует простой и быстрый (стандарт 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
складывается low
, mid
и high
, если не участвуют NULL или другие значения.
Ссылки:
Также читайте ниже.
Postgres 9,3-
Есть несколько методов:
@Phil предоставляет стандартный способ с CASE
утверждением (за исключением того sum(1)
, что это не стандартный способ). Мне нравится использовать более короткую форму:
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;
Если ваши значения соответствуют определенным в вашем вопросе (только 0
- 10
возможно), упростите далее:
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;
Немного короче, чуть быстрее.
Тонкие различия
Есть тонкие различия , когда по сравнению с sum()
в ответ Фила :
Самое главное, согласно документации :
Следует отметить, что за исключением count
этих функций, возвращается нулевое значение, когда строки не выбраны. В частности, sum
ни одна строка не возвращает ноль, а не ноль, как можно было бы ожидать, ...
count(*)
это стандартный способ и немного быстрее, чем sum(1)
. Снова, ноль против 0 применяется.
Любой из этих запросов (включая Фил) считает нулевые значения для total
. Если это не желательно, используйте вместо этого:
count(score) AS total_not_null
SQL Fiddle в pg 9.3.
дБ <> скрипка здесь в стр. 10.