👨💻 Казалось бы, агрегатные функции в SQL (SUM, AVG, COUNT) просто считают значения — что тут сложного? Но есть скрытая ловушка: как они ведут себя с NULL?
Давайте посмотрим на таблицу:
таблица orders:
id amount
1 100
2 NULL
3 200
1️⃣Посмотрим, как функции ведут себя с null значениями:
Выполним вот такой запрос:
SELECT
SUM(amount), -- 100 + 200 = 300 (NULL пропущен)
COUNT(amount), -- 2 (NULL не считается)
AVG(amount) -- (100+200)/2 = 150 (делим только на не-NULL)
FROM orders
Результат всегда рассчитывается только по НЕ-null значениям!
Имейте это ввиду.
2️⃣Что если в логике таблицы null означает на самом деле 0 и если мы этого не учтем то мы занизим метрику. Что делать? Нужно использовать функцию coalesce:
Выполним вот такой запрос:
SELECT
SUM(COALESCE(amount, 0)), -- 100 + 0 + 200 = 300
COUNT(COALESCE(amount, 0)), -- 3 (учтёт все строки, NULL стал 0)
AVG(COALESCE(amount, 0)) -- (100 + 0 + 200) / 3 = 100
FROM orders
Отлично мы не занизили метрику.
3️⃣ А что насчёт COUNT(*)?
COUNT(*) — считает все строки, независимо от значения поля. Т.е. учитывает и NULL, и не-NULL.
Выполним вот такой запрос:
SELECT
COUNT(*), -- 3 (все строки)
COUNT(amount), -- 2 (только не-NULL)
COUNT(COALESCE(amount, 0)) -- 3 (NULL стал 0)
FROM orders
Итог:
• COUNT(*) — нужен, когда важно узнать общее число строк (например, всю активность, включая пропуски).
• COUNT(поле) — только по реально заполненным значениям (NULL не попадает).
• COALESCE(поле, 0) — необходим, если логика отчёта требует трактовать NULL как 0 (например, “нет продаж” = 0), иначе метрики — сумма, среднее — будут ошибочными.
🍸 Если вы нашли пост для себя полезным, то накидывайте реакций, чтобы я понимал, что вам эта тема интересна!
❤️Поддержать канал бустами, чтобы у автора появился дополнительный функционал можно - здесь (это бесплатно и доступно с подпиской telegram premium)
❓ Знали о этих нюансах? Помню когда я учил SQL не многие проговаривали этот момент.