GROUP BY и агрегаты — считаем и проверяем цифры продукта

В прошлом уроке мы научились соединять таблицы через JOIN. Но часто тестировщику нужно не просто увидеть связанные строки, а посчитать что-то по ним: сколько студентов на курсе, какая средняя цена, сколько всего записей. Для этого в SQL есть агрегатные функции и группировка GROUP BY.

Чему научишься за этот урок:
— называть основные агрегатные функции: COUNT, SUM, AVG, MAX, MIN;
— объяснять, что делает GROUP BY и чем он отличается от запроса без группировки;
— писать запрос, который считает агрегат ОТДЕЛЬНО для каждой группы;
— проверять SQL-запросом цифру, которую продукт показывает в интерфейсе.

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

Агрегатные функции — это функции, которые считают одно итоговое значение по набору строк, а не возвращают сами строки. Основные:

COUNT() -> количество строк
SUM()   -> сумма значений столбца
AVG()   -> среднее значение столбца
MAX()   -> максимальное значение
MIN()   -> минимальное значение

Например, SELECT COUNT(*) FROM enrollments; посчитает ОДНО общее число — сколько всего строк (записей на курсы) в таблице enrollments, без разбивки по курсам.

GROUP BY — считаем отдельно по каждой группе

GROUP BY группирует строки по значению столбца, и агрегатная функция считается ОТДЕЛЬНО для каждой группы, а не для всей таблицы сразу. Сравним два запроса к одной и той же таблице enrollments(id, user_id, course_id):

Без GROUP BY:
SELECT COUNT(*) FROM enrollments;
-> одно общее число записей по всей таблице

С GROUP BY:
SELECT course_id, COUNT(*) FROM enrollments GROUP BY course_id;
-> по одной строке РЕЗУЛЬТАТА на каждый course_id,
   и в каждой строке - число записей именно на этот курс

То есть первый запрос скажет «всего 42 записи на курсы», а второй — «на курс 5 записано 30 человек, на курс 7 — 12 человек» (по строке на каждый курс отдельно).

Практическая польза: проверка цифры продукта

На странице курса в интерфейсе продукта может быть написано «На курсе 42 студента». Тестировщик может ПРОВЕРИТЬ это число SQL-запросом: SELECT COUNT(*) FROM enrollments WHERE course_id = 5; — и сравнить результат с тем, что показывает интерфейс. Если числа не совпадают — это баг: либо ошибка в расчёте на бэкенде, либо ошибка в отображении на фронтенде.

Итог:
— агрегатные функции COUNT, SUM, AVG, MAX, MIN считают одно итоговое значение по набору строк;
— GROUP BY группирует строки по столбцу, и агрегат считается ОТДЕЛЬНО для каждой группы;
— без GROUP BY агрегат даёт одно общее число по всей таблице;
— тестировщик может SQL-запросом проверить любую цифру, которую продукт показывает в интерфейсе.

Контрольный вопрос. Что делает агрегатная функция COUNT()?

АСчитает количество строк в наборе данных
БСортирует строки по возрастанию
ВУдаляет повторяющиеся строки

Подсказка: Название функции прямо намекает на то, что она делает — посчитай.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Контрольный вопрос. Что делает оператор GROUP BY?

АГруппирует строки по значению столбца, и агрегат считается отдельно для каждой группы
БСоединяет две таблицы между собой по внешнему ключу
ВОграничивает количество возвращаемых строк

Подсказка: Ключевое слово — «группирует»: подумай, что происходит с агрегатной функцией внутри каждой группы.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Контрольный вопрос. Что вернёт запрос SELECT COUNT(*) FROM enrollments; (без GROUP BY)?

АОдно общее число записей по всей таблице enrollments
БПо одной строке на каждого пользователя с его количеством записей
ВСписок всех курсов без повторов

Подсказка: В уроке прямо сравниваются запрос без GROUP BY и запрос с ним — вспомни разницу.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Контрольный вопрос. Какая функция посчитает среднюю цену по столбцу price?

АAVG(price)
БCOUNT(price)
ВMAX(price)

Подсказка: Нужна именно функция среднего значения — посмотри список агрегатных функций урока.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Контрольный вопрос. Запрос SELECT course_id, COUNT(*) FROM enrollments GROUP BY course_id; выполнили на таблице enrollments. Какие утверждения про результат верны (выбери все подходящие)?

Выберите все верные варианты.

АРезультат содержит по одной строке на каждый уникальный course_id
БВ каждой строке результата — число записей именно на этот курс, а не общее по всей таблице
ВРезультат — это всегда ровно одна строка с одним общим числом
ГБез GROUP BY этот же SELECT COUNT(*) дал бы одно общее число вместо разбивки по курсам

Подсказка: Сверь каждое утверждение с примером из урока про GROUP BY course_id — одно из четырёх описывает поведение БЕЗ группировки.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Контрольный вопрос. Как называется агрегатная функция, которая находит МАКСИМАЛЬНОЕ значение столбца? Ответь одним словом по-английски, как в уроке.

Подсказка: Посмотри список агрегатных функций урока — какая из них про максимум.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Задание. В интерфейсе продукта на странице курса с id=5 написано «На курсе 30 студентов». Какой SQL-запрос к таблице enrollments(id, user_id, course_id) проверит это число? Ответь одной командой SQL.

Подсказка: Нужен COUNT(*) с условием WHERE по нужному course_id.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Задание. Выполнили запрос SELECT course_id, COUNT(*) FROM enrollments GROUP BY course_id; и получили две строки результата: course_id=5 с числом 30, course_id=7 с числом 12. Сколько ВСЕГО строк в таблице enrollments (если это единственные два курса)? Ответь числом.

Подсказка: Сложи числа из каждой группы — это и есть общее количество записей по всей таблице.

✅ Готово, если: ты ввёл(а) верный ответ, и онлайн-проверка его приняла.

Проверить ответ →

Реальная проверка — на нашей платформе, бесплатно и без регистрации. Открыть задачу и ввести ответ →

Задание. Объясни в 2-3 предложениях: почему запрос SELECT COUNT(*) FROM enrollments; и запрос SELECT course_id, COUNT(*) FROM enrollments GROUP BY course_id; дают разные по смыслу результаты, хотя оба используют COUNT(*) на одной и той же таблице?

Критерий приёмки: объяснено, что первый запрос считает COUNT(*) по ВСЕЙ таблице целиком и даёт одно общее число; второй запрос сначала группирует строки по course_id, а затем считает COUNT(*) ОТДЕЛЬНО внутри каждой группы, поэтому даёт по строке результата на каждый курс с числом записей именно по этому курсу.

Подсказка: Вспомни, что делает GROUP BY с набором строк ДО того, как к ним применяется агрегатная функция.

✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.

Онлайн-проверка ответа появится позже

Задание. Тестировщик видит в интерфейсе продукта на странице каталога курсов надпись «Средняя цена курса: 4500 рублей». Опиши план проверки: (а) какой SQL-запрос к таблице courses(id, title, price) выполнить, чтобы проверить эту цифру; (б) что делать, если результат запроса не совпадёт с 4500 — на что в первую очередь обратить внимание при расследовании расхождения (например, может ли расхождение объясняться округлением или курсами без указанной цены).

Критерий приёмки: (а) назван запрос вида SELECT AVG(price) FROM courses; (б) описан план расследования: проверить, не отличается ли округление на фронтенде от округления в SQL-результате, и не исключены ли из среднего на бэкенде курсы с price = NULL или price = 0 (что сдвинуло бы среднее), — то есть указано хотя бы одно правдоподобное объяснение расхождения, а не просто «это баг».

Подсказка: AVG уже был в списке агрегатных функций урока; расхождение не всегда значит баг — подумай про округление и про курсы без цены.

✅ Готово, если: программа запускается без ошибок и выводит то, что просят в задании.

Онлайн-проверка ответа появится позже

Что дальше

Теперь вы умеете считать агрегаты по группам и проверять ими цифры продукта. В следующем уроке разберём подзапросы — SQL-запросы внутри других запросов, которые иногда удобнее JOIN для разовой ручной проверки.

Назад  ·  ↑ В начало урока  ·  ⌂ В начало курса  ·  Вперёд →

Школа Виктора Комлева