Этот урок открывает кластер про агрегацию. GROUP BY встречается почти в каждой задаче на собеседовании: «посчитай по отделам», «найди сумму по клиентам». Сам синтаксис знают все, а спотыкаются на одном правиле: что можно писать в SELECT рядом с группировкой. Запросы урока работают на учебной базе блока.
Как спрашивают
Что делает
GROUP BY? Почему запросSELECT department_id, name, max(salary) FROM employees GROUP BY department_idпадает в PostgreSQL?
Короткий ответ
GROUP BY раскладывает строки по группам с одинаковым значением ключа группировки, а агрегатные функции сворачивают каждую группу в одно значение. После группировки от группы остаётся одна строка, поэтому в SELECT можно писать только колонки группировки и агрегаты. Колонка name в группе своя у каждого сотрудника, и СУБД не знает, какое имя показать.
Разбор: конверты с чеками
Представь, что у тебя коробка чеков, и ты раскладываешь их по конвертам с подписью отдела. Потом на каждом конверте пишешь итог: сколько чеков, общая сумма, самый крупный. На конверте помещаются подпись и итоги. Написать на конверте «имя из чека» нельзя: чеков внутри несколько, имена разные.
SELECT department_id,
count(*) AS employees,
sum(salary) AS payroll,
max(salary) AS top
FROM employees
GROUP BY department_id
ORDER BY department_id;
department_id | employees | payroll | top
--------------+-----------+---------+-------
1 | 3 | 800000 | 300000
2 | 2 | 350000 | 200000
3 | 1 | 120000 | 120000
NULL | 1 | 180000 | 180000
Обрати внимание на последнюю строку. У Жанны нет отдела, и все строки с department_id IS NULL попали в одну группу. В WHERE два NULL не равны друг другу, как мы разбирали в уроке про NULL, а GROUP BY складывает их вместе: для группировки NULL считается одним значением.
Без GROUP BY агрегат считается по всей таблице и возвращает одну строку:
SELECT avg(salary)::int AS avg_salary, min(hired_at), max(hired_at)
FROM employees;
avg_salary | min | max
-----------+------------+-----------
207143 | 2018-11-20 | 2024-01-15
дальше после входа
Урок целиком открыт всем, кто вошёл. Войди по своему email, чтобы читать дальше.
Вход пока по приглашению. Если хочешь учиться, напиши Vassiliy.