Загрузка равна сумме фактических часов, делённой на рабочие дни × 8 часов, и умноженной на 100%. Сетка «сотрудник × месяц» сохраняет месяцы без трудозатрат.
На основе данных таблиц необходимо сформировать запрос, который будет выдавать % загрузки сотрудников.
Загрузка равна сумме фактических часов, делённой на рабочие дни × 8 часов, и умноженной на 100%. Сетка «сотрудник × месяц» сохраняет месяцы без трудозатрат.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
На основе данных таблиц необходимо сформировать запрос, который будет выдавать % загрузки сотрудников.
Исходные таблицы:
-
Графики работы (план) Год | Месяц | Количество рабочих дней 2025 | 10 | 20 2025 | 11 | 19
-
Трудозатраты по задачам (факт) Таб. номер сотрудника | ID задачи | Год | Месяц | Трудоемкость (часы) | ID подразделения 1 | 31 | 2025 | 10 | 40 | П1 2 | 32 | 2025 | 10 | 24 | П1
-
Задачи ID задачи | Описание | ID подразделения 31 | Разработать отчет по загрузке сотрудников | П1 32 | Разработать документ Поступление (акты, накладные) | П1
-
Подразделения ID подразделения | Название подразделения П1 | Бухгалтерия
-
Сотрудники Таб. номер сотрудника | ФИО сотрудника 1 | Иванов И.И. 2 | Петров П.П.
Таблица результата:
ФИО сотрудника | Год | Месяц | % Загрузки Иванов И.И. | 2025 | 10 | 25% Петров П.П. | 2025 | 10 | 15% Иванов И.И. | 2025 | 11 | 0% Петров П.П. | 2025 | 11 | 0%
Ответ
Загрузка равна сумме фактических часов, делённой на рабочие дни × 8 часов, и умноженной на 100%. Сетка «сотрудник × месяц» сохраняет месяцы без трудозатрат.
Принимаем восьмичасовой рабочий день: 40 / (20 × 8) = 25%, 24 / (20 × 8) = 15%. Сначала агрегируем факт, затем присоединяем его к каждому сотруднику и каждому месяцу плана. Названия таблиц ниже условные, соответствуют таблицам из задания.
WITH actual AS (
SELECT employee_id, year, month, SUM(hours) AS hours
FROM task_effort
GROUP BY employee_id, year, month
)
SELECT e.name, p.year, p.month,
100.0 * COALESCE(a.hours, 0)
/ NULLIF(p.work_days * 8, 0) AS load_percent
FROM employees e
CROSS JOIN work_schedule p
LEFT JOIN actual a
ON a.employee_id = e.id
AND a.year = p.year AND a.month = p.month;
Таблицы задач и подразделений нужны только для дополнительных отборов; лишнее соединение может размножить часы. При нулевой норме запрос возвращает NULL, поскольку процент не определён. Для неполного рабочего дня понадобится индивидуальная норма сотрудника.