Агрегатные функции: COUNT, SUM, AVG, MIN, MAX
Содержание курса
COUNT(*) vs COUNT(столбец) и поведение NULL в агрегатных функциях
Разберём тонкость, которая часто даёт неожиданные результаты. Пусть таблица orders содержит пять строк, но в двух из них amount равен NULL — например, заказы зарегистрированы, но сумма ещё не проставлена.
SELECT
COUNT(*) AS все_строки,
COUNT(amount) AS строки_с_суммой,
SUM(amount) AS итого
FROM orders;
Результат:
| все_строки | строки_с_суммой | итого |
|---|---|---|
| 5 | 3 | … |
COUNT(*) считает строки — все, независимо от того, что в них записано. COUNT(amount) считает только те строки, где amount не равен NULL. Поэтому первое число — 5, второе — 3.
SUM, AVG, MIN, MAX ведут себя как COUNT(столбец): они просто игнорируют строки с NULL и работают только с теми значениями, которые есть. SUM(amount) сложит три ненулевых значения и вернёт их сумму. AVG поделит ту же сумму на 3, а не на 5 — это важно: среднее считается по фактически присутствующим значениям, а не по общему количеству строк.
Есть крайний случай: если NULL стоит в столбце у всех строк, SUM, AVG, MIN, MAX вернут NULL. Это логично — нечего агрегировать. А вот COUNT(*) в той же ситуации вернёт не NULL, а количество строк — он вообще никогда не возвращает NULL, даже для полностью пустой таблицы вернёт 0.
Практическое следствие: если вы хотите знать, сколько заказов у вас в системе — используйте COUNT(*). Если хотите знать, для скольких из них уже проставлена сумма — используйте COUNT(amount). Это разные вопросы, и разница проявляется именно там, где есть NULL.
