COUNT(*) и COUNT(column) в SQL: почему NULL меняет количество
Разбираем разницу COUNT(*), COUNT(column) и COUNT DISTINCT на пропусках, пользователях и денежных фактах.
Содержание статьи
После LEFT JOIN аналитик видит строки пользователей без заказов и удивляется, что COUNT(*) считает их, а COUNT(order_id) — нет. Почему COUNT(*) и COUNT(order_id) возвращают разные значения?
Рабочий вопрос
Почему COUNT(*) и COUNT(order_id) возвращают разные значения?
После LEFT JOIN аналитик видит строки пользователей без заказов и удивляется, что COUNT(*) считает их, а COUNT(order_id) — нет.
В отчёте по каналам COUNT(*) покажет всех пользователей, а COUNT(order_id) — пользователей с заказом, если order_id NULL у остальных.
Определение и grain
Одна строка результата должна описывать одну сущность и один период. Перед агрегацией проверь, что исходные строки не повторяют объект и что фильтры не меняют знаменатель незаметно.
Назови, что должно быть в числителе: строки, заполненные ключи или уникальные сущности. Проверяй результат на LEFT JOIN и пустой группе.
Если показатель строится по событиям, отдельно проверь повторную отправку, идентичность пользователя и часовой пояс. Если данные приходят из бизнес-системы, сопоставь техническое поле с тем, как команда реально принимает решение.
вопрос → объект → период → расчёт → проверка → решениеЛюбой пропущенный шаг может изменить смысл итогового числа.
Разбор примера
В отчёте по каналам COUNT(*) покажет всех пользователей, а COUNT(order_id) — пользователей с заказом, если order_id NULL у остальных.
Не копируй пример в рабочий отчёт вслепую. Сначала замени названия таблиц и полей, проверь кардинальность связей и запиши, какие строки должны попасть в результат. Хорошая адаптация сохраняет логику, но делает допущения видимыми.
| Шаг | Что проверить | Зачем |
|---|---|---|
| Определение | объект и период | не менять вопрос |
| Расчёт | Значение | получить воспроизводимое число |
| Ревью | крайний случай и baseline | не перепутать шум с сигналом |
Где расчёт ломается
Нельзя заменять COUNT DISTINCT на COUNT(*) после JOIN и считать, что количество строк равно пользователям.
Отдельно протестируй пустой результат, NULL, дубль, граничную дату и объект без связанной записи. Эти случаи не являются редкими исключениями: именно они чаще всего превращают рабочий показатель в красивую, но неверную цифру.
- Не смешивай зрелые и незрелые периоды без отдельной подписи.
- Не заменяй проверку качества тем, что запрос просто выполнился.
- Не делай причинный вывод из одного разреза.
Что показывает график
График здесь нужен не для украшения статьи. Он помогает увидеть форму сигнала: тренд, разрыв между сегментами, хвост распределения или этап, на котором теряется объект. Сначала прочитай оси и единицы, затем сравни с таблицей и только после этого формулируй вывод.
На визуализации «COUNT(*) и COUNT(column) в SQL: почему NULL меняет количество» сравнивай не только максимальное значение. Проверь, одинаковы ли базы, не скрыта ли неполная дата и не меняется ли знаменатель от категории к категории.
Условный учебный пример для проверки формы сигнала, а не данные конкретной компании.
Проверь на своих данных
Сделай таблицу users с одним NULL order_id и сравни три вида COUNT. Напиши определение каждой колонки.
После упражнения напиши вывод в двух версиях. Первая — техническая: какие строки и условия дали результат. Вторая — для команды: что изменилось, насколько это надёжно и какое действие стоит проверить. Если эти версии противоречат друг другу, вернись к определению показателя.
- Собери контрольный пример из пяти-десяти строк.
- Сверь итог с независимым способом расчёта.
- Проверь хотя бы один крайний случай.
- Зафиксируй дату, версию схемы и ограничение.
Решение и продолжение
Выбирай COUNT по смыслу объекта. Подпись «orders» должна означать заказы, а не строки после соединения.
Сильный аналитический материал не обещает абсолютной уверенности. Он показывает, как получить число, где оно может ошибиться и какое решение можно принять уже сейчас. Такой формат хорошо переносится в дашборд, SQL-тренажёр, собеседование и рабочее обсуждение с командой.
Материалы по теме
SQL-проверки уникальности и NULL: базовый контроль перед отчётом
Чеклист SQL-проверок для ключей, NULL, ссылочной целостности и пустых групп перед публикацией метрики или дашборда.

Операторы сравнения и логика в SQL: AND, OR, NOT и NULL
Трёхзначная логика SQL на практике: почему NOT IN возвращает пустоту, где AND незаметно съедает OR и как собрать длинный фильтр так, чтобы его можно было проверить.
WHERE и HAVING в SQL: разница на примерах аналитики
Понятное сравнение WHERE и HAVING в SQL: фильтрация строк до GROUP BY, фильтрация групп после агрегации и типичные ошибки аналитика.