> SmartGate

Агрегатные функции

COUNT, SUM, AVG, MIN, MAX — количество, сумма, среднее

Теория

При работе с таблицей не всегда требуется рассматривать каждую строку по отдельности. Зачастую необходимо получить обобщённые итоговые данные по группе значений, то есть по нескольким строкам.

Например необходимо узнать:

• сколько сотрудников работает в компании;
• какая средняя зарплата у работников;
• у какого товара самая высокая цена;
• сколько всего заказов оформлено;
• какая минимальная и максимальная зарплата встречается в таблице.

Такого рода задачи ложатся на плечи агрегатных функций.

Агрегатная функция обрабатывает набор строк и выдаёт одно значение, которое можно назвать итоговым для этого набора. Она, по сути, объединяет множество строк в одно число или значение. Например, из всех зарплат в таблице сотрудников можно вычислить среднее значение. Или, посчитав все строки с заказами, можно получить одно число — их общее количество.

Основные агрегатные функции:

• COUNT() — считает количество строк или значений в наборе;
• SUM() — складывает (суммирует) значения;
• AVG() — находит среднее значение;
• MIN() — показывает минимальное значение;
• MAX() — показывает максимальное значение.

Важно: агрегатные функции обычно не учитывают NULL. Если значение в столбце отсутствует, оно просто не участвует в расчёте. Например, AVG(salary) будет считать среднюю зарплату только по тем работникам, у которых зарплата указана.

Отдельно запомните конструкцию COUNT(*). Она считает строки целиком по таблице. А вот COUNT(column) считает только строки по указанному столбцу и при этом не учитывает значения NULL.

Агрегатные функции можно использовать не только сами по себе, но и в выражениях. Их можно складывать, вычитать, делить и умножать. Например, можно посчитать разницу между максимальной и минимальной зарплатой или узнать среднюю стоимость заказа.

Синтаксис

SELECT COUNT(*)                      -- считаем количество строк в таблице
FROM workers;                        -- берём данные из таблицы workers

SELECT MAX(salary) - MIN(salary)     -- считаем разницу между максимальной и минимальной зарплатой
FROM workers;                        -- берём данные из таблицы workers
SQL
Обычно агрегатная функция указывается в SELECT. В круглых скобках функции пишем столбец, по которому нужно сделать расчёт.

Например, COUNT(salary) считает, в скольких строках столбца salary есть значение. Если в каких-то строках есть NULL, они в подсчёт не попадут.

Конструкция COUNT(*) работает иначе. Она считает не значения конкретного столбца, а просто количество строк по таблице.

Функции SUM(), AVG(), MIN() и MAX() работают с числовыми данными и возвращают одно итоговое число:

• SUM() — сумму;
• AVG() — среднее;
• MIN() — минимальное значение;
• MAX() — максимальное значение.

Результат агрегатных функций можно использовать в выражениях. Например, можно написать MAX(salary) - MIN(salary) и получить разницу между самой большой и самой маленькой зарплатой.

Примеры

1. Сколько всего работников в таблице

Самый базовый пример. Запрос считает все строки в таблице workers и показывает общее количество строк (в данном случае работников).

🔄 Попробуйте изменить запрос:

  • • Поменяйте псевдоним total_workers на workers_count
  • • Попробуйте выполнить такой же запрос для таблицы orders

2. Сколько работников получают зарплату больше 90000

Здесь дополнительно используется знакомый оператор WHERE. Сначала SQL отбирает только работников с зарплатой больше 90000, а потом COUNT(*) считает, сколько таких строк, удовлетворяющих условию, получилось.

🔄 Попробуйте изменить запрос:

  • • Поменяйте условие на salary >= 100000
  • • Попробуйте узнать, сколько работников получают меньше 70000

3. Средняя зарплата работников из конкретного отдела

Сначала выбираются только работники из отдела department_id = 2, а потом для них считается средняя зарплата.

🔄 Попробуйте изменить запрос:

  • • Поменяйте номер отдела на другой
  • • Попробуйте вместо AVG(salary) найти максимальную зарплату в отделе 2

4. Разница между COUNT(*) и COUNT(status)

Самое интересное. COUNT(*) считает все строки таблицы orders. А COUNT(status) считает только те строки, где в столбце status есть значение. Если статус не указан и там стоит NULL, такая строка во второй подсчёт уже не попадёт.

🔄 Попробуйте изменить запрос:

  • • Замените status на order_date и сравните результат
  • • Попробуйте выполнить такой же запрос для таблицы users и сравнить COUNT(*) с COUNT(city)

5. Разница между максимальной и минимальной зарплатой

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

🔄 Попробуйте изменить запрос:

  • • Поменяйте имя результата salary_range на diff_salary
  • • Попробуйте найти разницу между максимальной и минимальной зарплатой в отделе 3

6. Средняя стоимость двух товаров вместе

Выражение можно использовать и внутри агрегатной функции. Сначала для каждой строки считается price * 2, а потом по результату находится среднее.

🔄 Попробуйте изменить запрос:

  • • Замените price * 2 на price + 100

7. Разница между COUNT(city) и COUNT(DISTINCT city)

Давайте вспомним, зачем нужен DISTINCT. COUNT(city) считает все непустые значения в столбце city, включая повторы. А COUNT(DISTINCT city) считает только разные города без повторений. Если, например, десять пользователей живут в 'Москве', в первом подсчёте все десять строк попадут в результат, а во втором 'Москва' даст только одно уникальное значение.

🔄 Попробуйте изменить запрос:

  • • Уберите DISTINCT из второго выражения и сравните результат
  • • Попробуйте выполнить такой же запрос для поля status в таблице orders

Типичные ошибки

Путают COUNT(*) и COUNT(column) COUNT(*) считает все строки таблицы. COUNT(salary) считает только строки, где в столбце salary есть не NULL значение. Забывают, что WHERE срабатывает раньше агрегатной функции Сначала SQL отбирает строки по условию, и только потом агрегатная функция считает итог по оставшимся данным. Думают, что AVG() учитывает NULL как ноль Нет, NULL просто исключается из расчёта. Не используют арифметику с агрегатными функциями Агрегаты можно комбинировать. Например, MAX(salary) - MIN(salary) — это нормальное и очень полезное выражение. Пытаются применять SUM() и AVG() к текстовым столбцам Эти функции предназначены для числовых данных. Забывают добавить DISTINCT, когда нужно посчитать уникальные значения, и добавляют его, когда это не нужно COUNT(department_id) считает все непустые значения столбца, включая повторы. Если нужно узнать, сколько разных отделов есть в таблице, надо писать COUNT(DISTINCT department_id). Но если ваша задача — посчитать все строки или все заполненные значения, включая повторы, DISTINCT только исказит результат.

Практика

Проверь себя

Ответьте на вопросы, чтобы закрепить материал:

1
Чем отличается COUNT(*) от COUNT(salary)?
2
Напишите запрос, который посчитает, сколько товаров в таблице products стоят больше 50000.
3
Сколько товаров относится к категории 'Аксессуары'? Введите число.
4
Что вернёт запрос SELECT COUNT(DISTINCT category) FROM products;?
5
Напишите запрос, который посчитает общую стоимость всех товаров из категории 'Сеть'.
6
В каком случае DISTINCT действительно нужен?
7
Напишите запрос, который покажет разницу между максимальной ценой товара и средней ценой товара в таблице products.
8
Сколько отделов хранится в таблице departments? Введите число.