Условие
Как функция COUNT(*) работает с NULL-значениями? Чем она отличается от COUNT(col)?
Решение
| Выражение | Что считает |
|---|---|
COUNT(*) |
Все строки, включая те, где все колонки NULL |
COUNT(1) |
То же, что COUNT(*) |
COUNT(col) |
Только строки, где col IS NOT NULL |
COUNT(DISTINCT col) |
Уникальные не-NULL значения |
Пример
-- таблица employees
-- id | name | manager_id
-- 1 | Иван | NULL ← без менеджера
-- 2 | Маша | 1
-- 3 | Петя | 1
-- 4 | NULL | 2
SELECT
COUNT(*) AS total, -- 4
COUNT(name) AS with_name, -- 3 (NULL не учитывается)
COUNT(manager_id) AS with_manager, -- 3
COUNT(DISTINCT manager_id) AS uniq_managers -- 2 (1 и 2)
FROM employees;Применение
-- сколько сотрудников БЕЗ менеджера
SELECT COUNT(*) - COUNT(manager_id) AS no_manager FROM employees;
-- то же через FILTER (PostgreSQL) или CASE
SELECT COUNT(*) FILTER (WHERE manager_id IS NULL) FROM employees;
SELECT SUM(CASE WHEN manager_id IS NULL THEN 1 ELSE 0 END) FROM employees;Фишка с COUNT(DISTINCT) и NULL
SELECT COUNT(DISTINCT col) FROM (VALUES (1),(1),(2),(NULL),(NULL)) t(col);
-- 2: NULL'ы вообще не считаются как «значение»Подводные камни
COUNT(col1, col2)работает не везде. В PostgreSQL — синтаксическая ошибка. В некоторых СУБД считает строки, где обе колонки не-NULL.AVG(col),SUM(col),MIN(col)тоже игнорируют NULL — может казаться, что данные «потерялись».COUNT(*) OVER ()в оконной функции — считает все строки в рамках партиции, без учёта NULL в выражении.
Эталонный ответ
COUNT(*) считает все строки, включая полностью NULL. COUNT(col) игнорирует NULL в этой колонке. COUNT(DISTINCT col) — уникальные не-NULL значения.