Агрегация и группировка

Агрегатные функции: 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.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.