Уроки модуля (3/4)
Группировка с помощью GROUP BY
В модуле 2 вы узнали, что COUNT(*), AVG(...), SUM(...) сокращают все
строк в одну строку результата. Но что, если вы хотите среднюю зарплату?
для каждого отдела, а не для всей компании? Вам нужна одна строка per
группа. Это работа GROUP BY.
Синтаксис
SELECT grouping_column, AGGREGATE_FUNCTION(...)
FROM table
GROUP BY grouping_column;Прочтите по-английски: "разделите строки на группы, имеющие одинаковое значение
grouping_column, и для каждой группы вычислите агрегат ".
-- 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:
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 должен быть:
- один из столбцов группировки (например,
department_id,d.name) или - внутри агрегатной функции (например,
AVG(salary),COUNT(*)).
-- 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-х человек?"_ — однозначного ответа нет, и
поэтому двигатель отказывается.
Попробуйте это
Для каждого отдела подсчитайте, сколько в нем сотрудников. Верните два столбца: название отдела (departments.name) и количество сотрудников. Одна строка на отдел.
Показать подсказку
Агрегируйте с помощью COUNT(*) и группируйте по d.name. SELECT должен содержать только столбец группировки и агрегат.
Решение доступно после 3 попыток
Обзор упражнения
Для каждого отдела (departments.name) вычислите среднюю зарплату (AVG(salary)) его сотрудников, отсортированную от самой высокой к самой низкой.
Показать подсказку
AVG(e.salary) как совокупность, ГРУППИРОВАТЬ ПО d.name, ПОРЯДОК ПО среднему значению DESC.
Решение доступно после 3 попыток