🙏 Спасибо за поддержку проекта. В прошлом месяце мы собрали только $32. Этого хватает на серверы, но не на разработку, поэтому новых уроков и функций в этом месяце не будет. Пожалуйста, поддержите следующий месяц. Поддержать →
SQL код скопирован в буфер обмена

Время чтения: ~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 и научимся строить агрегаты по категориям.

Попробуйте решить следующие задачи, чтобы закрепить материал этого урока.

  1. Определить границы стоимости проката
  2. Количество фильмов с актёром
  3. Найти минимальную, максимальную и среднюю продолжительность
  4. Средняя продолжительность фильма по категории
  5. Самые разноплановые актёры