← Назад к вопросам

Что такое агрегатные функции в SQL? Приведите примеры.?

1.3 Junior🔥 111 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Агрегатные функции (Aggregate Functions) — это функции SQL, которые выполняют вычисления над набором строк и возвращают одно значение. Они используются для получения статистики и сводок по данным.

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

1. COUNT — подсчёт количества строк

Синтаксис:

COUNT(столбец) — подсчитывает ненулевые значения
COUNT(*) — подсчитывает все строки (включая NULL)
COUNT(DISTINCT столбец) — подсчитывает уникальные значения

Примеры:

-- Сколько всего сотрудников?
SELECT COUNT(*) 
FROM employees;
-- Результат: 150

-- Сколько сотрудников имеют опыт (не NULL)?
SELECT COUNT(experience_years) 
FROM employees;
-- Результат: 145 (5 записей имеют NULL)

-- Сколько разных отделов?
SELECT COUNT(DISTINCT department_id) 
FROM employees;
-- Результат: 12

-- Сколько заказов по каждому клиенту?
SELECT customer_id, COUNT(*) as order_count
FROM orders
GROUP BY customer_id;

Результат:

customer_id  order_count
1            5
2            12
3            3
...

2. SUM — сумма значений

Синтаксис:

SUM(столбец) — суммирует все значения (NULL игнорируются)
SUM(DISTINCT столбец) — сумма уникальных значений

Примеры:

-- Общая сумма продаж
SELECT SUM(amount) as total_sales
FROM orders;
-- Результат: 1234567.89

-- Сумма продаж по каждому месяцу
SELECT DATE_TRUNC('month', order_date) as month, SUM(amount)
FROM orders
GROUP BY DATE_TRUNC('month', order_date);

-- Результат:
month              sum
2025-01-01         50000
2025-02-01         75000
2025-03-01         120000

-- Сумма количества товара по складам
SELECT warehouse_id, SUM(quantity) as total_items
FROM inventory
GROUP BY warehouse_id;

3. AVG — среднее арифметическое

Синтаксис:

AVG(столбец) — средняя величина (NULL игнорируются)
AVG(DISTINCT столбец) — среднее уникальных значений

Примеры:

-- Средняя зарплата сотрудников
SELECT AVG(salary) as average_salary
FROM employees;
-- Результат: 85000.50

-- Средний размер заказа по клиентам
SELECT customer_id, AVG(amount) as avg_order
FROM orders
GROUP BY customer_id;

-- Средний рейтинг продукта
SELECT product_id, AVG(rating) as avg_rating
FROM reviews
WHERE rating IS NOT NULL
GROUP BY product_id;

-- Результат:
product_id  avg_rating
1           4.5
2           3.8
3           4.2

4. MIN и MAX — минимальное и максимальное значение

Синтаксис:

MIN(столбец) — минимальное значение
MAX(столбец) — максимальное значение

Примеры:

-- Самая низкая и высокая зарплата
SELECT MIN(salary) as min_salary, MAX(salary) as max_salary
FROM employees;
-- Результат: min_salary: 40000, max_salary: 250000

-- Самый ранний и последний заказ
SELECT MIN(order_date) as first_order, MAX(order_date) as last_order
FROM orders;

-- Цена товара с минимальной и максимальной стоимостью
SELECT 
  MIN(price) as cheapest,
  MAX(price) as most_expensive
FROM products;

-- Последний заказ каждого клиента
SELECT customer_id, MAX(order_date) as last_order_date
FROM orders
GROUP BY customer_id;

Группировка агрегатных функций

GROUP BY — группировка по одному столбцу:

-- Среднее количество заказов по отделам
SELECT 
  d.department_name,
  COUNT(e.id) as employee_count,
  AVG(e.salary) as avg_salary,
  MIN(e.salary) as min_salary,
  MAX(e.salary) as max_salary
FROM departments d
LEFT JOIN employees e ON d.id = e.department_id
GROUP BY d.id, d.department_name
ORDER BY avg_salary DESC;

-- Результат:
department_name  employee_count  avg_salary  min_salary  max_salary
IT               15              120000      90000       200000
Sales            20              95000       50000       180000
HR               8               75000       60000       95000

GROUP BY с множественными столбцами:

-- Продажи по городам и месяцам
SELECT 
  city,
  DATE_TRUNC('month', order_date) as month,
  COUNT(*) as orders,
  SUM(amount) as total_amount,
  AVG(amount) as avg_order
FROM orders
GROUP BY city, DATE_TRUNC('month', order_date)
ORDER BY month DESC, city;

-- Результат:
city      month              orders  total_amount  avg_order
Москва    2025-03-01         50      250000        5000
Москва    2025-02-01         45      225000        5000
СПб       2025-03-01         30      120000        4000
СПб       2025-02-01         28      112000        4000

Фильтрация агрегатных данных — HAVING

HAVING — условие для агрегатных функций:

-- Отделы с средней зарплатой выше 100K
SELECT 
  department_id,
  AVG(salary) as avg_salary
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 100000;

-- Результат:
department_id  avg_salary
1              120000
3              105000

-- Клиенты, потратившие больше 50K
SELECT 
  customer_id,
  SUM(amount) as total_spent
FROM orders
GROUP BY customer_id
HAVING SUM(amount) > 50000
ORDER BY total_spent DESC;

Разница между WHERE и HAVING:

-- WHERE — фильтрует строки ДО группировки
-- HAVING — фильтрует ПОСЛЕ группировки

SELECT 
  department_id,
  COUNT(*) as employee_count,
  AVG(salary) as avg_salary
FROM employees
WHERE salary > 60000  -- Фильтруем сотрудников с зарплатой > 60K
GROUP BY department_id
HAVING COUNT(*) > 5   -- Потом берём отделы с > 5 сотрудниками

Практические примеры

Пример 1: Анализ продаж

SELECT 
  p.category,
  COUNT(o.id) as total_orders,
  SUM(od.quantity) as total_items_sold,
  SUM(od.quantity * od.price) as revenue,
  AVG(od.price) as avg_price,
  MIN(od.price) as min_price,
  MAX(od.price) as max_price
FROM products p
JOIN order_details od ON p.id = od.product_id
JOIN orders o ON od.order_id = o.id
WHERE o.order_date >= '2025-01-01'
GROUP BY p.category
HAVING COUNT(o.id) > 10
ORDER BY revenue DESC;

Пример 2: Анализ клиентов

SELECT 
  c.name,
  COUNT(o.id) as order_count,
  SUM(o.amount) as total_spent,
  AVG(o.amount) as avg_order_value,
  MIN(o.order_date) as first_order,
  MAX(o.order_date) as last_order,
  DATEDIFF(DAY, MIN(o.order_date), MAX(o.order_date)) as customer_lifetime
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name
HAVING COUNT(o.id) > 0
ORDER BY total_spent DESC;

Пример 3: Отчёт по складам

SELECT 
  w.name as warehouse,
  COUNT(DISTINCT p.id) as unique_items,
  SUM(i.quantity) as total_quantity,
  AVG(i.quantity) as avg_items_per_sku,
  MIN(i.quantity) as min_stock,
  MAX(i.quantity) as max_stock,
  SUM(i.quantity * p.price) as total_value
FROM warehouses w
JOIN inventory i ON w.id = i.warehouse_id
JOIN products p ON i.product_id = p.id
GROUP BY w.id, w.name
ORDER BY total_value DESC;

Window Functions vs Aggregate Functions

Отличие:

-- AGGREGATE (возвращает 1 строку на группу)
SELECT 
  department_id,
  AVG(salary) as avg_salary
FROM employees
GROUP BY department_id;
-- Результат: 10 строк (для 10 отделов)

-- WINDOW (возвращает строку для каждого сотрудника)
SELECT 
  id,
  name,
  salary,
  AVG(salary) OVER (PARTITION BY department_id) as dept_avg_salary
FROM employees;
-- Результат: 150 строк (все сотрудники)

Обработка NULL в агрегатных функциях

-- COUNT игнорирует NULL
SELECT 
  COUNT(*) as total_rows,           -- 150
  COUNT(commission) as with_commission -- 120 (30 NULL)
FROM employees;

-- SUM, AVG, MIN, MAX тоже игнорируют NULL
SELECT 
  SUM(bonus) as total_bonus,        -- Суммирует только ненулевые
  COUNT(bonus) as employees_with_bonus,  -- Количество ненулевых
  AVG(bonus) as avg_bonus           -- Среднее по ненулевым
FROM employees;

-- Если хочешь обработать NULL, используй COALESCE
SELECT 
  AVG(COALESCE(bonus, 0)) as avg_including_zeros
FROM employees;

Производительность агрегатных функций

Оптимизация:

  1. Индексируй столбцы в GROUP BY
  2. Используй WHERE перед GROUP BY (уменьшает количество строк)
  3. Избегай агрегирования больших текстовых полей
  4. Используй DISTINCT осторожно (может быть медленно)
-- Медленно
SELECT COUNT(DISTINCT customer_name) FROM orders;

-- Быстрее (если есть customer_id)
SELECT COUNT(DISTINCT customer_id) FROM orders;

Заключение

Агрегатные функции — это мощный инструмент для анализа данных:

  • COUNT — количество строк
  • SUM — сумма значений
  • AVG — среднее значение
  • MIN/MAX — минимум/максимум
  • GROUP BY — группировка данных
  • HAVING — фильтрация после группировки

Эти функции используются в 90% аналитических запросов и отчётов. Понимание их работы — обязательный навык для системного аналитика.