Перейти к содержанию
Educora
Начальный14 мин6 / 22

Агрегатные функции: COUNT, SUM, AVG, MIN, MAX

Превращай множество строк в одно число: считай строки, суммируй значения, находи среднее, минимум и максимум.

Проверь себя
В этом уроке ты узнаешь
  • Пользоваться пятью основными агрегатными функциями
  • Объяснять разницу между COUNT(*), COUNT(столбец) и COUNT(DISTINCT столбец)
  • Сочетать агрегаты с WHERE и знать, как на них влияет NULL

Учителю нужен не балл каждого ученика, а средний балл класса. Владелец магазина хочет знать общую сумму продаж, а не просматривать каждый заказ. Ответ на такие вопросы — не список строк, а одно число. В SQL такие числа вычисляют агрегатные функции.

Что такое агрегатная функция?

Определение
Агрегатная функция

Функция, которая берёт значения из множества строк и вычисляет по ним один результат. Обычная функция (например, ROUND) работает с каждой строкой отдельно, а агрегатная — со всеми строками сразу.

ФункцияЧто возвращает
COUNT(*)количество строк
COUNT(x)количество значений x, не равных NULL
SUM(x)сумму значений
AVG(x)среднее значение
MIN(x)наименьшее значение
MAX(x)наибольшее значение

COUNT: подсчёт

У COUNT три формы. COUNT(*) считает все строки. COUNT(email) считает только строки, в которых email заполнен, — у двух учеников e-mail равен NULL, поэтому получается 10. COUNT(DISTINCT city) даёт число разных городов.

SQL
SELECT COUNT(*)             AS students,
       COUNT(email)         AS with_email,
       COUNT(DISTINCT city) AS cities
FROM students;
▸ Ожидаемый результат
students | with_email | cities
12 | 10 | 7

SUM, AVG, MIN и MAX

В одном запросе можно написать несколько агрегатов сразу. Среднее часто получается длинной дробью (здесь 293,558), поэтому округлим его с помощью ROUND. Результат всегда — одна строка, ведь вся таблица подытоживается как одна группа.

SQL
SELECT SUM(stock)            AS total_items,
       ROUND(AVG(price), 2)  AS avg_price,
       MIN(price)            AS cheapest,
       MAX(price)            AS most_expensive
FROM products;
▸ Ожидаемый результат
total_items | avg_price | cheapest | most_expensive
1086 | 293.56 | 3.2 | 1450

MIN и MAX работают не только с числами, но и с текстом и датами. Для дат в формате YYYY-MM-DD MIN даёт самую раннюю дату, а MAX — самую позднюю.

SQL
SELECT MIN(order_date) AS first_order,
       MAX(order_date) AS last_order
FROM orders;
▸ Ожидаемый результат
first_order | last_order
2025-01-15 | 2025-07-07

Вычисления с агрегатами

Результат агрегата — обычное число, поэтому с ним можно производить вычисления. MAX(age) - MIN(age) даёт разницу между наибольшим и наименьшим возрастом. Чтобы найти процент учеников с e-mail, делим COUNT(email) на COUNT(*) и умножаем на 100. Осторожно: 100 * 10 / 12 — деление целых чисел, оно даёт 83; для точного результата пишем 100.0.

SQL
SELECT MAX(age) - MIN(age) AS age_range,
       100 * COUNT(email) / COUNT(*) AS int_pct,
       ROUND(100.0 * COUNT(email) / COUNT(*), 1) AS pct_with_email
FROM students;
▸ Ожидаемый результат
age_range | int_pct | pct_with_email
3 | 83 | 83.3
int_pct потерял дробную часть из-за деления целых чисел.

Агрегаты и WHERE

WHERE срабатывает до агрегата: сначала строки фильтруются, затем вычисление идёт только по оставшимся строкам. Ниже мы берём только зачисления на курс 1 (Algebra): 4 ученика, средний балл 87,3.

SQL
SELECT COUNT(*)             AS enrollments,
       ROUND(AVG(score), 1) AS avg_score,
       MIN(score)           AS min_score,
       MAX(score)           AS max_score
FROM enrollments
WHERE course_id = 1;
▸ Ожидаемый результат
enrollments | avg_score | min_score | max_score
4 | 87.3 | 75 | 97
Пример задачи

Какова общая стоимость всех товаров на складе?

Показать решение
Стоимость запаса каждого товара — price * stock.
Внутри агрегата можно писать выражение: SUM(price * stock).
СУБД сначала вычисляет произведение для каждой строки, а затем складывает: 40260,6.
SQL
SELECT SUM(price * stock) AS warehouse_value
FROM products;
▸ Ожидаемый результат
warehouse_value
40260.6
SQL
SELECT AVG(age) AS avg_age
FROM students;
▸ Ожидаемый результат
avg_age
15.5
Задание

Подведи итоги по курсу номер 1 (Algebra): число зачислений (students), средний балл, округлённый до 1 знака после запятой (avg_score), и лучший балл (best).

Задание · SQL
SELECT COUNT(*) AS students
       -- add avg_score and best
FROM enrollments
WHERE course_id = 1;
▸ Ожидаемый результат
students | avg_score | best
4 | 87.3 | 97
Задание

Для категории Electronics найди число товаров (products), общий остаток на складе (total_stock) и самую низкую цену (cheapest).

Задание · SQL
SELECT
  -- three aggregates here
FROM products
WHERE category = 'Electronics';
▸ Ожидаемый результат
products | total_stock | cheapest
4 | 63 | 120.5

Главное

  • Агрегатная функция вычисляет один результат по множеству строк: COUNT, SUM, AVG, MIN, MAX.
  • COUNT(*) считает все строки, COUNT(x) — не равные NULL, а COUNT(DISTINCT x) — разные значения.
  • WHERE выполняется до агрегата, поэтому считаются только отфильтрованные строки.
  • Агрегаты (кроме COUNT(*)) пропускают значения NULL.
  • Не смешивай агрегат с обычным столбцом без GROUP BY — в большинстве СУБД это ошибка.

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
В таблице students COUNT(*) даёт 12, а COUNT(email) — 10. Почему?