Модульні уроки (3/4)
Групування за допомогою GROUP BY
У модулі 2 ви дізналися, що COUNT(*), AVG(...), SUM(...) зменшують усі
рядків до одного рядка результату. Але що, якщо ви хочете середню зарплату
для кожного відділу, а не для всієї компанії? Вам потрібен один рядок на
група. Це робота 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) як сукупний, GROUP BY d.name, ORDER BY середній DESC.
Рішення доступне після 3 спроб