Короткий ответ
GROUP BY группирует строки по значениям указанных колонок, а агрегатные функции считают значение по каждой группе; в SELECT можно использовать только колонки из GROUP BY или результаты агрегатных функций, иначе непонятно, какое значение негруппированной колонки показывать для группы из нескольких строк.
Как это работает подробнее
СУБД сначала логически разбивает результат на группы по значениям указанных колонок, затем применяет агрегатную функцию к каждой группе отдельно, возвращая одну строку на группу.
Пример кода
example.sql
SELECT department_id, COUNT(*) AS employees, AVG(salary) AS avg_salary
FROM employees
GROUP BY department_id;
-- Ошибка в PostgreSQL, если добавить employees.name в SELECT без агрегатной функции и без GROUP BY по ней:
-- ERROR: column "employees.name" must appear in the GROUP BY clause or be used in an aggregate functionЧто использовать на практике
- Практика. Типичная ошибка — попытка вывести негруппированную колонку «для примера»; PostgreSQL в этом случае выдаст ошибку компиляции запроса, в отличие от некоторых других СУБД, которые могут вернуть произвольное значение.
Подводные камни
- Ошибка. Путают HAVING и WHERE, забывают, что WHERE фильтрует строки до группировки и не может ссылаться на результат агрегатной функции.