Перейти к основному содержимому
Модуль 3 · Урок 3 из 411/57 в курсе~10 min
Уроки модуля (3/4)

Группировка с помощью GROUP BY

В модуле 2 вы узнали, что COUNT(*), AVG(...), SUM(...) сокращают все строк в одну строку результата. Но что, если вы хотите среднюю зарплату? для каждого отдела, а не для всей компании? Вам нужна одна строка per группа. Это работа GROUP BY.

Синтаксис

SQL
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM   table
GROUP BY grouping_column;

Прочтите по-английски: "разделите строки на группы, имеющие одинаковое значение grouping_column, и для каждой группы вычислите агрегат ".

SQL
-- Average salary per department:
SELECT department_id, AVG(salary) AS average
FROM   employees
GROUP BY department_id;

Результат содержит одну строку для каждого отдельного department_id, найденного в employees. Вы получите 5 строк: по одной для каждого из 4 отделов (1, 2, 3, 4) плюс один для NULL (Андреа Коста).

С JOIN для читаемых имен

Часто требуется группировать по department_id, но отображать имя объекта. отдел. Вы объединяете GROUP BY с JOIN:

SQL
SELECT d.name AS department,
       COUNT(*)    AS count,
       AVG(e.salary) AS average_salary
FROM   employees   AS e
JOIN   departments AS d ON e.department_id = d.id
GROUP BY d.name
ORDER BY count DESC;

Это полноценный запрос бизнес-аналитики: в трёх строках он сообщает вам, сколько сотрудников в каждом отделе и сколько они зарабатывают на средний, отсортированный от большего к меньшему.

Золотое правило

При использовании GROUP BY каждый столбец в SELECT должен быть:

  1. один из столбцов группировки (например, department_id, d.name) или
  2. внутри агрегатной функции (например, AVG(salary), COUNT(*)).
SQL
-- ERROR: first_name is neither in GROUP BY nor inside an aggregate
SELECT department_id, first_name, AVG(salary)
FROM   employees
GROUP BY department_id;

PostgreSQL возвращает явную ошибку (столбец "должен присутствовать в GROUP BY или использоваться в агрегатной функции"). Это обычное дело в начале недели ошибка: если вы это видите, остановитесь и спросите себя: «В чем ценность first_name для группы из 3-х человек?"_ — однозначного ответа нет, и поэтому двигатель отказывается.

Попробуйте это

Упражнение#sql.m3.l3.e1
Попыток: 0Загрузка…

Для каждого отдела подсчитайте, сколько в нем сотрудников. Верните два столбца: название отдела (departments.name) и количество сотрудников. Одна строка на отдел.

Загрузка редактора…
Показать подсказку

Агрегируйте с помощью COUNT(*) и группируйте по d.name. SELECT должен содержать только столбец группировки и агрегат.

Решение доступно после 3 попыток

Обзор упражнения

Упражнение#sql.m3.l3.e2
Попыток: 0Загрузка…

Для каждого отдела (departments.name) вычислите среднюю зарплату (AVG(salary)) его сотрудников, отсортированную от самой высокой к самой низкой.

Загрузка редактора…
Показать подсказку

AVG(e.salary) как совокупность, ГРУППИРОВАТЬ ПО d.name, ПОРЯДОК ПО среднему значению DESC.

Решение доступно после 3 попыток