Средний ~25 мин чтения

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

Урок 4 из 6 в курсе SQL: быстрый старт

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

агрегатные функции считают, суммируют и находят максимумы по группам строк.

Почему это важно: Аналитика, дашборды, статистика — всё это строится на агрегации. Без GROUP BY приходится тащить данные в приложение и считать там, что медленнее.

Главная идея

GROUP BY группирует строки по значению столбца; агрегатные функции (COUNT, SUM, AVG, MAX, MIN) вычисляют значение для каждой группы.

Как это выглядит на практике

  1. SELECT category, COUNT(*) FROM products GROUP BY category — количество товаров по категориям.
  2. SELECT user_id, SUM(amount) FROM orders GROUP BY user_id — сумма заказов на пользователя.
  3. HAVING SUM(amount) > 1000 фильтрует уже сгруппированные результаты.
  4. ORDER BY total DESC LIMIT 10 — топ-10 покупателей по сумме.

Что происходит под капотом

  • В SELECT можно указывать только столбцы из GROUP BY или агрегатные функции — иначе запрос некорректен.
  • COUNT(*) считает все строки; COUNT(column) — только строки, где column не NULL.
  • HAVING выполняется после GROUP BY; WHERE — до. Фильтруйте через WHERE там, где возможно.
  • Агрегация на больших таблицах без индексов требует full table scan — это медленно.

Типичные ошибки и заблуждения

  • Ошибка: HAVING и WHERE взаимозаменяемы. WHERE фильтрует строки до агрегации, HAVING — после.
  • Ошибка: COUNT(*) и COUNT(id) всегда одинаковы. COUNT(column) игнорирует NULL.
  • Ошибка: GROUP BY возвращает отсортированные результаты. Без ORDER BY порядок не гарантирован.
  • Ошибка: агрегатные запросы всегда медленные. С правильными индексами и покрывающими индексами — нет.

Ключевые выводы

  • GROUP BY группирует строки; агрегатные функции считают значения для каждой группы.
  • HAVING фильтрует после группировки; WHERE — до.
  • COUNT(*) считает строки; COUNT(col) — строки без NULL.
  • Выносите фильтрацию в WHERE, а не HAVING — это эффективнее.

Термины урока

GROUP BY: группировка строк по значению столбца.
COUNT / SUM / AVG / MAX / MIN: агрегатные функции.
HAVING: условие фильтрации агрегированных групп.
Aggregate function: функция, вычисляющая одно значение для группы строк.

Связь с работой backend-разработчика

Считайте статистику в SQL, а не в коде приложения. БД оптимизирована для агрегации больших объёмов данных; загрузка тысяч строк в память приложения для подсчёта — антипаттерн.

Мини-разбор реальной ситуации

Дашборд аналитики тянет все заказы за год (100 000 строк) в Rails, считает суммы в Ruby и возвращает JSON. Запрос занимает 8 секунд. Замена на SELECT user_id, SUM(amount) FROM orders GROUP BY user_id выполняется за 120 мс в БД.

Что запомнить

  • Агрегируйте в SQL, а не в приложении.
  • WHERE быстрее HAVING — используйте его для фильтрации строк.
  • GROUP BY без ORDER BY не гарантирует порядок результатов.

Итог

GROUP BY и агрегатные функции переносят вычисления туда, где данные — в базу. Это быстрее, проще и масштабируемее, чем обработка в коде приложения.