Время чтения: ~8 минут
Агрегатные функции в SQL помогают превращать набор строк в итоговые метрики: количество, сумму, среднее, минимум и максимум. В этом уроке вы разберете базовые агрегаты на примерах из Sakila и научитесь выбирать правильный вариант подсчета в зависимости от задачи. К концу урока вы сможете уверенно использовать COUNT, SUM, AVG, MIN и MAX в аналитических запросах.
Базовые агрегатные функции в SQL
В предыдущих уроках вы работали с выборкой отдельных строк. Теперь переходим к следующему важному шагу: как получать сводные показатели по данным.
Агрегатные функции особенно важны для отчетов и аналитики, потому что позволяют быстро ответить на вопросы вроде «сколько?», «на какую сумму?» и «какое среднее значение?».
Основные агрегатные функции
COUNT() — считает количество строк
Базовый синтаксис:
COUNT(expression)
Пример:
SELECT COUNT(*) AS total_payments
FROM payment;
Результат: запрос возвращает общее количество строк в таблице payment.
COUNT(column) и COUNT(*)
Эти две формы выглядят похоже, но работают по-разному:
COUNT(*)считает все строки в результате;COUNT(column)считает только строки, где значениеcolumnнеNULL.
Если в столбце есть NULL, результат COUNT(column) может быть меньше, чем у COUNT(*).
SELECT
COUNT(*) AS total_rentals,
COUNT(return_date) AS returned_rentals
FROM rental;
Пояснение: total_rentals считает все аренды, а returned_rentals только те, где return_date заполнен.
COUNT(DISTINCT ...) — считает уникальные значения
Когда нужно посчитать не количество строк, а количество уникальных значений, используют COUNT(DISTINCT column).
SELECT COUNT(DISTINCT customer_id) AS unique_customers
FROM payment;
Результат: запрос возвращает число уникальных клиентов, которые совершали платежи, даже если у одного клиента много строк в payment.
На практике это важно для задач вроде «сколько разных клиентов купили товар», где обычный COUNT(*) завысит итог из-за повторов.
SUM() — вычисляет сумму
SELECT SUM(amount) AS total_amount
FROM payment;
Результат: возвращает сумму значений столбца amount.
SUM(amount) игнорирует NULL. Если все значения в выборке равны NULL, результат будет NULL.
AVG() — вычисляет среднее
SELECT AVG(amount) AS average_amount
FROM payment;
Результат: возвращает среднее значение amount по не-NULL строкам.
Если нужно учитывать строки с NULL в знаменателе, можно использовать один из вариантов:
SELECT
AVG(amount) AS avg_ignore_null,
AVG(COALESCE(amount, 0)) AS avg_include_null_as_zero,
SUM(amount) / COUNT(*) AS avg_sum_div_all_rows
FROM payment;
MAX() — находит максимальное значение
SELECT MAX(amount) AS max_amount
FROM payment;
Результат: возвращает наибольшее значение в столбце amount.
MIN() — находит минимальное значение
SELECT MIN(amount) AS min_amount
FROM payment;
Результат: возвращает наименьшее значение в столбце amount.
И MIN(), и MAX() игнорируют NULL. Если все значения NULL, результат будет NULL.
MIN(column) и ORDER BY ... LIMIT 1 — всегда ли одно и то же
Не всегда.
SELECT MIN(column_name)
FROM table_name;
SELECT column_name
FROM table_name
ORDER BY column_name
LIMIT 1;
MIN(column_name)ищет минимум среди не-NULLзначений;ORDER BY ... LIMIT 1возвращает первую строку после сортировки;- если
NULLсортируется первым, второй запрос может вернутьNULL, аMIN()при этом вернет минимальное не-NULLзначение.
Надежный вариант, эквивалентный MIN():
SELECT column_name
FROM table_name
WHERE column_name IS NOT NULL
ORDER BY column_name
LIMIT 1;
Практическое применение
Подсчет количества клиентов
SELECT COUNT(*) AS total_customers
FROM customer;
Сумма продаж по сотрудникам
SELECT
staff_id,
SUM(amount) AS staff_total
FROM payment
GROUP BY staff_id;
Средний платеж по клиенту
SELECT
customer_id,
AVG(amount) AS avg_payment
FROM payment
GROUP BY customer_id;
Количество уникальных клиентов с оплатами
SELECT COUNT(DISTINCT customer_id) AS paying_customers
FROM payment;
Часто задаваемые вопросы
Чем COUNT(*) отличается от COUNT(column)?
COUNT(*) считает все строки результата. COUNT(column) считает только строки, где в указанном столбце нет NULL.
Когда использовать COUNT(DISTINCT ...)?
Когда нужно посчитать число уникальных значений, а не общее число строк. Например, уникальных клиентов, а не количество всех платежей.
Почему AVG может давать неожиданное значение?
Потому что AVG(column) игнорирует NULL. Если нужно учитывать такие строки в знаменателе, применяют COALESCE или делят SUM(column) на COUNT(*).
Вопросы для собеседования
Что такое агрегатные функции в SQL?
Это функции, которые вычисляют итог по набору строк: например, количество (COUNT), сумму (SUM) или среднее (AVG). Они возвращают одно значение на группу или на весь результат.
В чем разница между COUNT(*), COUNT(column) и COUNT(DISTINCT column)?
COUNT(*) считает все строки, COUNT(column) считает только не-NULL значения столбца, а COUNT(DISTINCT column) считает количество уникальных не-NULL значений.
Как MIN и ORDER BY ... LIMIT 1 могут дать разный результат?
Если в столбце есть NULL и СУБД сортирует их первыми, ORDER BY ... LIMIT 1 может вернуть NULL, а MIN() вернет минимальное не-NULL значение.
Ключевые выводы этого урока:
- Агрегатные функции помогают быстро получать сводные метрики по данным.
COUNT(*),COUNT(column)иCOUNT(DISTINCT ...)решают разные задачи подсчета.SUM,AVG,MINиMAXобычно игнорируютNULL, что важно учитывать в аналитике.COUNT(DISTINCT ...)нужен, когда важно число уникальных сущностей, а не число строк.- Корректная работа с
NULLнапрямую влияет на точность отчетов.
В следующем уроке мы рассмотрим группировку данных с помощью GROUP BY и научимся строить агрегаты по категориям.