Функция COUNT() в SQL: COUNT(*), COUNT(col) и COUNT(DISTINCT)
COUNT() считает строки, но ведёт себя по-разному в зависимости от аргумента. COUNT(*) считает все строки. COUNT(col) считает строки, где col НЕ NULL. COUNT(DISTINCT col) считает уникальные не-NULL значения. Путаница между этими тремя формами — частый источник неверных метрик и любимый вопрос собеседования.
COUNT(col) молча пропускает NULL — если считаешь COUNT(phone), а у половины юзеров телефон пустой, получишь заниженное число и не заметишь. Для «сколько всего строк» бери COUNT(*), для «сколько с заполненным полем» — COUNT(col), для «сколько уникальных» — COUNT(DISTINCT). Ещё грабли: COUNT(DISTINCT) по большим данным тяжёлый, в ClickHouse для оценки берут uniq().
Где спрашивают на собеседовании
Разницу COUNT(*) / COUNT(col) / COUNT(DISTINCT) спрашивают почти на каждом SQL-собесе — это фильтр на внимательность к NULL. Типичная задача: «посчитай уникальных пользователей», где COUNT(*) вместо COUNT(DISTINCT user_id) раздувает метрику в разы из-за нескольких событий на юзера.
FAQ: частые вопросы про COUNT
В чём разница COUNT(*) и COUNT(колонка)?
COUNT(*) считает все строки, включая те, где значения NULL. COUNT(колонка) считает только строки, где эта колонка НЕ NULL. Если пропусков нет, результат совпадёт, иначе COUNT(колонка) будет меньше.
Считает ли COUNT значения NULL?
COUNT(*) — да (это подсчёт строк). COUNT(колонка) и COUNT(DISTINCT колонка) — нет, NULL игнорируются. Это стандартное поведение агрегатов: NULL в подсчёт значений не входит.
Как посчитать уникальные значения?
COUNT(DISTINCT колонка) вернёт число уникальных не-NULL значений. Для подсчёта уникальных пользователей: COUNT(DISTINCT user_id).