JavaRush /Курсы /SQL SELF /Группировка данных (GROUP BY): синтаксис и структура

Группировка данных (GROUP BY): синтаксис и структура

SQL SELF
8 уровень , 0 лекция
Открыта

Представьте, что вы работаете с тысячами строк данных — как найти в них смысл? Тут на сцену выходит оператор GROUP BY — настоящий дирижёр в оркестре SQL. Он берёт разрозненные данные и превращает их в чёткую мелодию: считает, группирует, подводит итоги. Хотите узнать, сколько заказов сделал каждый клиент, сколько студентов на каждом курсе или как распределяются зарплаты по отделам? Всё это — работа GROUP BY. Сегодня мы разберёмся, как с ним подружиться и извлекать максимум пользы из ваших таблиц.

Группировка — это процесс объединения строк, которые имеют одинаковые значения в одном или нескольких столбцах, в логические группы. Она позволяет применять агрегатные функции отдельно к каждой группе.

Представьте, что у вас есть таблица сотрудников, и вы хотите узнать среднюю зарплату по каждому отделу. Один отдел — одна группа. SQL использует GROUP BY, чтобы разделить таблицу сотрудников на группы по отделам, а затем применяет AVG() к каждой группе.

Синтаксис GROUP BY

Главное правило использования группировки в SQL: если вы используете GROUP BY, то каждый столбец, который не является частью агрегатной функции, должен быть указан в GROUP BY.

Синтаксис:

SELECT столбец1, 
       агрегатная_функция(столбец2)
FROM таблица
GROUP BY столбец1;

Шаги работы:

  1. Укажите столбец, по которому хотите сгруппировать данные, в GROUP BY.
  2. Используйте агрегатные функции для вычисления значений в группах.
  3. Все столбцы в SELECT, но не входящие в агрегатные функции, должны быть перечислены в GROUP BY. Да, SQL строг в этом плане, и если вы забудете, он напомнит вам об этом ошибкой.

Пример: Группировка студентов по факультетам

Допустим, у нас есть таблица students, которая хранит данные о студентах:

id name faculty gpa
1 Alex Lin ComputerSci 3.8
2 Maria Chi Math 3.5
3 Anna Song ComputerSci 4.0
4 Otto Art Math 3.9
5 Liam Park Physics 3.7

Теперь мы хотим узнать средний балл (GPA) по каждому факультету. Для этого напишем запрос с GROUP BY:

SELECT faculty, AVG(gpa) AS avg_gpa
FROM students
GROUP BY faculty;

Результат:

faculty avg_gpa
ComputerSci 3.9
Math 3.7
Physics 3.7

SQL сначала разделил данные на группы по значению столбца faculty, а затем применил функцию AVG() к каждой группе.

Особенности работы с GROUP BY

  1. Требования к столбцам в SELECT

SQL требует, чтобы все столбцы, которые вы указываете в SELECT, но не используете в агрегатных функциях (например, SUM(), COUNT()), были упомянуты в GROUP BY. Это связано с тем, что без группировки SQL не может понять, какие значения выводить.

Попробуйте выполнить следующий запрос и получите ошибку:

SELECT name, AVG(gpa)
FROM students
GROUP BY faculty;

Ошибка: столбец name не указан в GROUP BY. Чтобы исправить это, добавьте name в GROUP BY:

SELECT name, AVG(gpa)
FROM students
GROUP BY faculty, name;

Но это уже сгруппирует данные на уровне конкретных студентов — не совсем то, что нам нужно было изначально.

  1. Группировка по нескольким столбцам

Вы можете группировать данные не только по одному столбцу, но и по нескольким. Например, в дополнение к факультетам хотим группировать студентов по их именам. Просто добавьте второй столбец в GROUP BY:

SELECT faculty, name, AVG(gpa) AS avg_gpa
FROM students
GROUP BY faculty, name;

Изначальная таблица:

id name faculty gpa
1 Alex Lin ComputerSci 3.8
2 Maria Chi Math 3.5
3 Anna Song ComputerSci 4.0
4 Otto Art Math 3.9
5 Liam Park Physics 3.7

Результат:

faculty name avg_gpa
ComputerSci Alex Lin 3.8
ComputerSci Anna Song 4.0
Math Maria Chi 3.5
Math Otto Art 3.9
Physics Liam Park 3.7
  1. Группировка с использованием нескольких агрегатных функций

Не ограничивайте себя только одной функцией! Например, хотим подсчитать количество студентов на факультете и вычислить средний балл:

SELECT faculty,
       COUNT(*) AS student_count, 
       AVG(gpa) AS avg_gpa
FROM students
GROUP BY faculty;

Исходная таблица:

id name faculty gpa
1 Alex Lin ComputerSci 3.8
2 Maria Chi Math 3.5
3 Anna Song ComputerSci 4.0
4 Otto Art Math 3.9
5 Liam Park Physics 3.7

Результат:

faculty student_count avg_gpa
ComputerSci 2 3.9
Math 2 3.7
Physics 1 3.7

Особенности группировки в SQL: что можно и что нельзя выбирать

Запросы с группировкой писать легко, но скорее всего половина ваших запросов работать не будет. Группировка происходит немного не так, как мы привыкли делать у себя в голове.

Если у вас в SQL-запросе есть GROUP BY, то думайте о всех колонках результата как о вычисляемых выражениях. Колонки в SELECT могут быть только двух типов:

  • вычисляться агрегатными функциями на основе колонок группы.
  • браться из GROUP BY - по ним должна быть группировка.

Если вы выполняете GROUP-BY-запрос по таблице студентов, то в результирующей таблице у вас не может быть конкретных студентов! У вас может быть средний рост, средний вес, средний бал. Такой код работать не будет:

SELECT faculty, name
FROM students
GROUP BY faculty;

Давайте попробуем разобраться почему.

Оператор GROUP BY faculty разобьет студентов таблицы students на группы с одинаковым faculty у каждой группы. Т.к. у всех студентов группы одинаковый faculty, то можно сказать, что атрибут faculty есть у группы студентов. Но name у всех студентов разные. Поэтому атрибута name у группы нет.

Оператор GROUP BY faculty, gender разобьет студентов таблицы students на группы с одинаковым faculty и gender у каждой группы. Поэтому у всех студентов каждой группы будут одинаковые faculty и gender. Поэтому можно сказать, что у самой группы студентов есть атрибуты faculty и gender. Но единого name у группы по прежнему нет.

Так писать можно:

SELECT faculty, gender
FROM students
GROUP BY faculty, gender;

Можно даже так:

SELECT
    faculty, 
    gender, 
    AVG(age) as group_avg_age,  -- Значение вычисляется на основе age значений группы студентов
    MAX(high) as group_high     -- Значение вычисляется на основе high значений группы студентов
FROM students
GROUP BY faculty, gender;

Но просто использовать age и high в SELECT в нашем случае нельзя.

Типичные ошибки при использовании GROUP BY

Когда вы начнёте писать запросы с GROUP BY, вот несколько подводных камней, которые могут встретиться на пути:

  1. Указаны не все столбцы в SELECT. Помните, каждый столбец, который не является агрегатом, должен быть указан в GROUP BY. Иначе SQL не поймёт, как его отображать.

  2. Группировка по NULL. NULL значения считаются отдельной группой. Если в вашем столбце есть NULL, SQL создаст группу для NULL.

  3. Избыточные группы. Если вы случайно добавите слишком много столбцов в GROUP BY, вы можете получить слишком детализированные результаты, которые сложнее анализировать.

Теперь вы знаете как эффективно группировать данные с помощью GROUP BY. Это один из самых мощных инструментов в SQL, который позволяет легко работать с агрегированными данными и создавать структурированные отчёты. Далее мы продолжим углубляться в магию группировки и узнаем, как настраивать дополнительные фильтры с помощью HAVING.

2
Задача
SQL SELF, 8 уровень, 0 лекция
Недоступна
Группировка клиентов по странам
Группировка клиентов по странам
2
Задача
SQL SELF, 8 уровень, 0 лекция
Недоступна
Подсчёт количества продуктов по категориям
Подсчёт количества продуктов по категориям
Комментарии (7)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Ra Уровень 35 Student
25 августа 2025
Если c Group by используется Order by, то её поля тоже должны быть в Select. Либо сортировать по полям Group by.
Anemon Уровень 13 Expert
16 августа 2025
🤓
Ra Уровень 35 Student
1 августа 2025

SELECT faculty, name, AVG(gpa) AS avg_gpa
FROM students
GROUP BY faculty, name;
Вот это моей глупой голове непонятно. GROUP BY faculty, name; - какой физический смысл этого? для какой цели мы это написали? Мы группируем записи по группам, и в этих группах ещё группируем записи по одинаковым именам. (Итоговая группировка получается по людям, а не группам) И получаем средние оценки для людей записей с одинаковыми именами, принадлежащих к одной группе? По моему это надо расписать. А если будет GROUP BY faculty, name, age; Будут группы по одинаковому возрасту, людей с одинаковым именем, учащимся на одном факультете? (Итоговая группировка по возрасту!) Самым важным получается самый крайний правый член отбора.
Anemon Уровень 13 Expert
16 августа 2025
Тоже трудно дошло, возможно потому что статью опять писал ИИ хд Тут нет важных отдельных моментов, группировка происходит по всем параметрам, которые не используются аггрегатными функциями, поэтому порядок именно того что входит в группировку не важен. А остальные обязаны собраться в "один" результат, т.е. если нет функции что сотворит единичный результат из множества, то эта категория обязана быть в группировке, либо не быть вовсе. Навряд ли я объяснил лучше.. хд Но ты, вижу, за 15 дней прошел 50 уровней, так что тебе это уже не нужно.)
Ra Уровень 35 Student
22 августа 2025
Что-то я тогда загнался над простыми вещами 😂 Вот более наглядный пример, надо получить: Клиента, Месяц, Сумму заказов этого клиента за месяц Группировка сначала по клиенту, потом по его покупкам за месяц.

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    total_amount NUMERIC(10, 2)
);

SELECT
    o.customer_id,
    DATE_TRUNC('month', o.order_date) AS month,
    SUM(o.total_amount) AS total_sales
FROM orders o
GROUP BY o.customer_id, DATE_TRUNC('month', o.order_date);
Ra Уровень 35 Student
24 августа 2025
Так ещё нагляднее
Slevin Уровень 34
2 сентября 2025
Технически, основная группировка будет происходить по самым "уникальным" столбцам. Это может быть как и имя, так и возраст, так и рост, смотря какие значения более уникальные. То есть "уникальность" столбца задает узкое горлышко сортировки. Если я конечно правильно себе представляю процесс.