Агрегатные функции: COUNT, SUM, AVG, MIN, MAX
Что такое агрегатные функции и зачем они нужны? 🔍
Агрегатные функции — это мощные инструменты SQL, которые позволяют выполнять вычисления над набором строк и возвращать одно результирующее значение. Они незаменимы при анализе данных, формировании отчётов и подведении статистики.
SELECT COUNT(*) FROM orders; -- Сколько всего заказов?
SELECT SUM(amount) FROM sales; -- Какая общая сумма продаж?
Функция COUNT — считаем записи 🧮
COUNT() — самая популярная агрегатная функция. Она просто подсчитывает количество строк в результирующем наборе. Есть несколько вариантов её использования:
-- Подсчёт всех строк в таблице (включая NULL)
SELECT COUNT(*) FROM employees;
-- Подсчёт только не-NULL значений в конкретной колонке
SELECT COUNT(department_id) FROM employees;
-- Подсчёт уникальных значений
SELECT COUNT(DISTINCT department_id) FROM employees;
💡 Производительность: COUNT(*) обычно работает быстрее COUNT(column_name), так как не проверяет значения на NULL.
SUM и AVG — работаем с числами ➕
Когда нужно просуммировать значения или найти среднее, на помощь приходят SUM() и AVG():
-- Общая сумма зарплат в компании
SELECT SUM(salary) FROM employees;
-- Средняя зарплата по отделам
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id;
⚠️ Важно: Эти функции работают ТОЛЬКО с числовыми типами данных. Попытка применить их к текстовым данным вызовет ошибку.
MIN и MAX — находим экстремумы 📊
Эти функции помогают быстро найти минимальное и максимальное значение в наборе данных:
-- Самая высокая и низкая зарплата в компании
SELECT MAX(salary), MIN(salary) FROM employees;
-- Первый и последний заказ клиента
SELECT MIN(order_date), MAX(order_date)
FROM orders
WHERE customer_id = 42;
🎯 Лайфхак: С MAX() и MIN() можно работать не только с числами, но и с датами, строками (по алфавиту) и другими сравниваемыми типами данных.
Группировка с GROUP BY 🧩
Агрегатные функции раскрывают весь свой потенциал в сочетании с GROUP BY. Это позволяет получать статистику по группам:
-- Количество сотрудников в каждом отделе
SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id;
-- Средний чек по месяцам
SELECT
EXTRACT(MONTH FROM order_date) AS month,
AVG(total_amount) AS avg_check
FROM orders
WHERE EXTRACT(YEAR FROM order_date) = 2023
GROUP BY EXTRACT(MONTH FROM order_date)
ORDER BY month;
Фильтрация агрегированных данных с HAVING 🎯
Когда нужно отфильтровать результаты агрегации, WHERE не подойдёт — нужен HAVING:
-- Отделы с более чем 5 сотрудниками
SELECT department_id, COUNT(*) as emp_count
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;
-- Товары, которые продались на сумму > 10000
SELECT product_id, SUM(quantity*price) as total_sales
FROM order_items
GROUP BY product_id
HAVING SUM(quantity*price) > 10000;
Комбинирование нескольких функций 🧪
Мощь SQL проявляется при комбинации нескольких агрегатных функций в одном запросе:
-- Статистика по зарплатам в каждом отделе
SELECT
department_id,
COUNT(*) AS employees,
ROUND(AVG(salary), 2) AS avg_salary,
MIN(salary) AS min_salary,
MAX(salary) AS max_salary,
SUM(salary) AS total_salary
FROM employees
WHERE active = TRUE
GROUP BY department_id
HAVING COUNT(*) > 3
ORDER BY avg_salary DESC;
Распространённые ошибки и как их избегать 🚧
1. Использование агрегатных функций без GROUP BY:
-- Неправильно (department_id не в GROUP BY)
SELECT department_id, AVG(salary) FROM employees;
-- Правильно
SELECT department_id, AVG(salary) FROM employees GROUP BY department_id;
2. Фильтрация агрегированных данных через WHERE:
-- Неправильно (WHERE не работает с агрегатами)
SELECT department_id, COUNT(*)
FROM employees
WHERE COUNT(*) > 5
GROUP BY department_id;
-- Правильно (используем HAVING)
SELECT department_id, COUNT(*)
FROM employees
GROUP BY department_id
HAVING COUNT(*) > 5;
3. Путаница между COUNT(*) и COUNT(column):
-- Считает ВСЕ строки (включая NULL)
SELECT COUNT(*) FROM employees;
-- Считает только строки, где email не NULL
SELECT COUNT(email) FROM employees;