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

Групування за допомогою GROUP BY

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

Рішення доступне після 3 спроб