← Назад к вопросам
Какие знаешь агрегатные функции в SQL?
1.3 Junior🔥 201 комментариев
#Базы данных (SQL)
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Агрегатные функции в SQL
Агрегатные функции вычисляют одно значение из множества строк. Они используются с GROUP BY и часто применяются в аналитике и отчётах.
1. COUNT — подсчёт строк
Подсчитывает количество строк, соответствующих условию.
-- Подсчёт всех пользователей
SELECT COUNT(*) as total_users FROM users;
-- Подсчёт только заполненных email
SELECT COUNT(email) as users_with_email FROM users;
-- Подсчёт уникальных значений
SELECT COUNT(DISTINCT country) as countries FROM users;
-- С условием WHERE
SELECT COUNT(*) as active_users FROM users WHERE status = 'active';
-- Группировка
SELECT country, COUNT(*) as user_count FROM users GROUP BY country;
В Python с SQLAlchemy:
from sqlalchemy import func, select
from models import User
# COUNT(*)
query = select(func.count()).select_from(User)
count = session.execute(query).scalar()
# COUNT DISTINCT
query = select(func.count(func.distinct(User.country)))
distinct_countries = session.execute(query).scalar()
# COUNT с условием
query = select(func.count()).select_from(User).where(User.status == 'active')
active_count = session.execute(query).scalar()
2. SUM — сумма значений
Складывает все значения в колонке.
-- Общая сумма продаж
SELECT SUM(amount) as total_sales FROM orders;
-- Сумма по группам
SELECT customer_id, SUM(amount) as customer_total FROM orders GROUP BY customer_id;
-- Сумма с фильтром
SELECT SUM(amount) as monthly_total FROM orders WHERE DATE_TRUNC('month', created_at) = '2024-01';
-- NULL не учитывается в SUM
SELECT SUM(commission) FROM sales; -- Игнорирует NULL значения
В Python:
from sqlalchemy import func
from models import Order
# SUM всех заказов
query = select(func.sum(Order.amount))
total = session.execute(query).scalar()
# SUM по группам
from sqlalchemy import select
query = select(
Order.customer_id,
func.sum(Order.amount).label('total')
).group_by(Order.customer_id)
results = session.execute(query).all()
for customer_id, total in results:
print(f"Customer {customer_id}: {total}")
3. AVG — среднее значение
Вычисляет среднее арифметическое.
-- Средняя цена товара
SELECT AVG(price) as average_price FROM products;
-- Средний рейтинг по категориям
SELECT category, AVG(rating) as avg_rating FROM products GROUP BY category;
-- AVG с HAVING (фильтр на результат агрегации)
SELECT category, AVG(rating) as avg_rating FROM products
GROUP BY category
HAVING AVG(rating) > 4.0;
В Python:
from sqlalchemy import func
from models import Product
# AVG
query = select(func.avg(Product.price))
average_price = session.execute(query).scalar()
# AVG с GROUP BY
query = select(
Product.category,
func.avg(Product.rating).label('avg_rating')
).group_by(Product.category)
for category, rating in session.execute(query):
print(f"{category}: {rating}")
4. MIN и MAX — минимум и максимум
Находят наименьшее и наибольшее значения.
-- Самый дешёвый и дорогой товар
SELECT
MIN(price) as cheapest,
MAX(price) as most_expensive
FROM products;
-- Дата первого и последнего заказа
SELECT
MIN(created_at) as first_order,
MAX(created_at) as last_order
FROM orders;
-- MIN/MAX по группам
SELECT
customer_id,
MIN(amount) as smallest_order,
MAX(amount) as largest_order
FROM orders
GROUP BY customer_id;
В Python:
from sqlalchemy import func
from models import Product, Order
# MIN и MAX
query = select(
func.min(Product.price).label('min_price'),
func.max(Product.price).label('max_price')
)
min_price, max_price = session.execute(query).first()
# С GROUP BY
query = select(
Order.customer_id,
func.min(Order.amount).label('min'),
func.max(Order.amount).label('max')
).group_by(Order.customer_id)
5. GROUP_CONCAT / STRING_AGG — объединение строк
Объединяет строки в одну с разделителем.
-- MySQL: GROUP_CONCAT
SELECT user_id, GROUP_CONCAT(skill SEPARATOR ', ') as skills
FROM user_skills
GROUP BY user_id;
-- PostgreSQL: STRING_AGG
SELECT user_id, STRING_AGG(skill, ', ') as skills
FROM user_skills
GROUP BY user_id;
-- Oracle: LISTAGG
SELECT user_id, LISTAGG(skill, ', ') WITHIN GROUP (ORDER BY skill) as skills
FROM user_skills
GROUP BY user_id;
Результат:
user_id | skills
1 | Python, JavaScript, Go
2 | Java, C++
6. STDDEV / VARIANCE — стандартное отклонение и дисперсия
Для статистического анализа.
-- Стандартное отклонение цен
SELECT STDDEV(price) as price_std_dev FROM products;
-- Дисперсия оценок
SELECT category, VARIANCE(rating) as rating_variance
FROM products
GROUP BY category;
7. PERCENTILE — процентили
Полезны для аналитики распределения данных.
-- PostgreSQL: PERCENTILE_CONT
SELECT
PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY price) as p25,
PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY price) as median,
PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY price) as p75
FROM products;
-- Результат: квартили распределения цен
8. Оконные функции (Window Functions) с агрегацией
Онцевые функции более мощны чем обычная агрегация.
-- Бегущий итог
SELECT
order_date,
amount,
SUM(amount) OVER (ORDER BY order_date) as running_total
FROM orders
ORDER BY order_date;
-- Ранг в группе
SELECT
product_id,
amount,
RANK() OVER (ORDER BY amount DESC) as rank
FROM sales;
-- Среднее относительно группы
SELECT
name,
salary,
AVG(salary) OVER (PARTITION BY department) as dept_avg,
salary - AVG(salary) OVER (PARTITION BY department) as diff_from_avg
FROM employees;
В Python:
from sqlalchemy import func, over, window
from models import Order
# Оконная функция - бегущий итог
running_total = func.sum(Order.amount).over(
order_by=Order.order_date
)
query = select(Order.order_date, Order.amount, running_total)
9. Практический пример: комплексный аналитический запрос
SELECT
DATE_TRUNC('month', order_date)::date as month,
COUNT(*) as order_count,
SUM(amount) as total_revenue,
AVG(amount) as avg_order_value,
MIN(amount) as min_order,
MAX(amount) as max_order,
STDDEV(amount) as revenue_stddev,
STRING_AGG(DISTINCT category, ', ') as categories
FROM orders
WHERE status = 'completed'
GROUP BY DATE_TRUNC('month', order_date)
HAVING COUNT(*) > 10
ORDER BY month DESC;
В Python:
from sqlalchemy import func, text
from sqlalchemy.sql import select
from models import Order
query = select(
func.date_trunc('month', Order.order_date).label('month'),
func.count().label('count'),
func.sum(Order.amount).label('total'),
func.avg(Order.amount).label('avg'),
func.min(Order.amount).label('min'),
func.max(Order.amount).label('max'),
func.stddev(Order.amount).label('stddev')
).where(
Order.status == 'completed'
).group_by(
func.date_trunc('month', Order.order_date)
).having(
func.count() > 10
).order_by(
func.date_trunc('month', Order.order_date).desc()
)
results = session.execute(query).all()
Выводы
Основные агрегатные функции:
- COUNT — количество строк
- SUM, AVG — сумма и среднее
- MIN, MAX — экстремумы
- STRING_AGG — объединение строк
- STDDEV, VARIANCE — статистика
Важные правила:
- Используй GROUP BY с агрегатами
- HAVING фильтрует результаты агрегации
- NULL не учитывается в большинстве функций
- Оконные функции мощнее обычной агрегации
- Проверь документацию конкретной БД (синтаксис отличается)