Перейти к содержанию

Агрегаты и CASE

SQL агрегаты, GROUP BY и CASE

Этот блок учит «считать» и «группировать» данные: сколько заказов, сколько потратил пользователь и как писать условия прямо в SQL.


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

Самые популярные:

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

Пример: сколько заказов всего?

SQL
SELECT COUNT(*) AS orders_total
FROM orders;

Пример: сколько заказов по статусам?

SQL
SELECT status, COUNT(*) AS cnt
FROM orders
GROUP BY status
ORDER BY cnt DESC;

GROUP BY: сжать строки в группы

Если вы написали агрегат + обычные колонки, почти всегда нужен GROUP BY.

✅ корректно:

SQL
SELECT user_id, COUNT(*) AS cnt
FROM orders
GROUP BY user_id;

❌ некорректно (непонятно, какую created_at брать):

SQL
SELECT user_id, created_at, COUNT(*)
FROM orders;

HAVING: фильтр по группам

WHERE фильтрует строки до группировки, а HAVINGпосле.

Покажем пользователей, у кого 2+ заказа:

SQL
SELECT user_id, COUNT(*) AS cnt
FROM orders
GROUP BY user_id
HAVING COUNT(*) >= 2;

Считаем суммы заказов

Сумма по каждому заказу:

SQL
SELECT
  o.id AS order_id,
  SUM(oi.qty * oi.price) AS order_total
FROM orders o
JOIN order_items oi ON oi.order_id = o.id
GROUP BY o.id
ORDER BY o.id;

Сумма покупок по пользователю:

SQL
SELECT
  u.id,
  u.name,
  SUM(oi.qty * oi.price) AS total_spent
FROM users u
JOIN orders o      ON o.user_id = u.id
JOIN order_items oi ON oi.order_id = o.id
GROUP BY u.id, u.name
ORDER BY total_spent DESC;

CASE: если..., то...

CASE — это как if/else в SQL.

SQL
SELECT
  id,
  status,
  CASE
    WHEN status = 'paid' THEN 'Оплачен'
    WHEN status = 'new' THEN 'Новый'
    WHEN status = 'canceled' THEN 'Отменен'
    ELSE 'Неизвестно'
  END AS status_label
FROM orders
ORDER BY id;

GROUP BY vs оконные функции

sql-04-groupby-vs-window.svg GROUP BY уменьшает количество строк, оконные функции сохраняют строки и добавляют вычисления.