Число сотрудников с одинаковой зарплатой в каждом департаменте

42. Посчитать сотрудников с одинаковой зарплатой в каждом департаменте

Условие задачи:
Даны таблицы department и employee.

Необходимо для каждого департамента и каждой встречающейся в нём зарплаты вывести количество сотрудников, получающих эту зарплату.

Код:

CREATE TABLE department (
    id BIGSERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);

CREATE TABLE employee (
    id BIGSERIAL,
    surname VARCHAR(255) NOT NULL,
    name VARCHAR(255) NOT NULL,
    salary BIGINT NOT NULL,
    department_id BIGINT NOT NULL REFERENCES department(id)
);

Пример результата:

dep_name   | salary | employee_count
-----------+--------+---------------
Dep_name_1 | 1000   | 3
Dep_name_1 | 2000   | 4
Dep_name_2 | 2000   | 30

Спойлеры к решению

Подсказки
💡 Соедини сотрудников с департаментами по department_id.
💡 Группировать нужно одновременно по департаменту и зарплате.
💡 Для подсчёта сотрудников используй COUNT(*).
💡 Учитывай department.id, чтобы департаменты с одинаковыми названиями не объединились.

Решение
SELECT
    d.name AS dep_name,
    e.salary,
    COUNT(*) AS employee_count
FROM department d
JOIN employee e
    ON e.department_id = d.id
GROUP BY
    d.id,
    d.name,
    e.salary
ORDER BY
    d.name,
    e.salary;

Сначала сотрудники соединяются со своими департаментами:

e.department_id = d.id

Затем записи группируются по департаменту и зарплате:

GROUP BY
    d.id,
    d.name,
    e.salary

COUNT(*) возвращает количество сотрудников внутри каждой такой группы.

Например, если в одном департаменте три сотрудника получают 1000, а четыре сотрудника получают 2000, результат будет содержать две отдельные строки.

Вариант через оконную функцию:

SELECT DISTINCT
    d.name AS dep_name,
    e.salary,
    COUNT(*) OVER (
        PARTITION BY e.department_id, e.salary
    ) AS employee_count
FROM employee e
JOIN department d
    ON d.id = e.department_id
ORDER BY
    dep_name,
    salary;

Для этой задачи вариант с GROUP BY проще и естественнее, поскольку требуется получить одну строку на каждую пару «департамент — зарплата».