Короткий ответ
NULL означает «значение неизвестно/не записано», а 0 — это конкретное известное значение суммы; агрегатные функции вроде AVG() автоматически исключают NULL из расчёта, а 0 — нет, и это может сильно исказить результат.
Как это работает подробнее
в SQL агрегатные функции (AVG, SUM) по умолчанию игнорируют NULL, но учитывают 0 как валидное число. Если пропуски на самом деле означают «заказ отменён» или «ошибка записи», а не «сумма действительно равна нулю», смешение этих случаев даёт неверный средний чек.
Пример кода
Пример SQL
SELECT
avg(amount) AS aov_naive,
avg(amount) FILTER (WHERE amount > 0) AS aov_excl_zero,
count(*) FILTER (WHERE amount IS NULL) AS null_cnt,
count(*) FILTER (WHERE amount = 0) AS zero_cnt
FROM orders;Что использовать на практике
- Порядок действий. перед расчётом выясняю природу пропусков/нулей у владельца данных или в документации источника: технический сбой записи, отменённый заказ без возврата денег, тестовый заказ. В зависимости от причины либо исключаю строки, либо заполняю обоснованным значением, либо оставляю как есть.
Подводные камни
- Частые ошибки. автоматически заменять все NULL на 0 (или наоборот) без понимания причины; включать тестовые/отменённые заказы с amount=0 в расчёт AOV, занижая метрику; не документировать, как обработаны пропуски, что ломает воспроизводимость отчёта.