Войти Регистрация
Data base

239. Календарь: кто в какой день должен быть в офисе

Сложная

В work_modes — режимы работы сотрудников: табельный номер tab_num, период start_date – finish_date (оба включительно) и флаги d1–d5 — нужно ли быть в офисе с понедельника по пятницу (1 или 0). Периоды одного сотрудника не пересекаются.

Бессрочный режим записан с finish_date = 9999-12-31: для него концом считается end_da — дата окончания трудового договора, если она есть. У обычных режимов end_da не смотрим.

wplace_type = 1 — флаги действуют каждую неделю. wplace_type = 2 — гибрид: неделя по флагам чередуется с неделей дома. Недели отсчитываются от start_date: дни 0–6 — по флагам, 7–13 — дома (0), 14–20 — снова по флагам.

Постройте календарь с 1 по 14 сентября 2025 года для каждого сотрудника из таблицы: tab_num, day, to_be_at_office. Суббота, воскресенье и дни, не покрытые ни одним режимом, — NULL. Порядок — tab_num, day.

В работе: Планирование рабочих мест и пропусков в офис на месяц вперёд.

Таблицы

work_modes — одна строка — один период режима работы сотрудника

КолонкаТипЧто значит
tab_numintтабельный номер
start_datedateначало
finish_datedateконец, 9999-12-31 — бессрочно
wplace_typeint1 — каждую неделю, 2 — через неделю
d1smallintпонедельник: 1 — офис
d2smallintвторник
d3smallintсреда
d4smallintчетверг
d5smallintпятница
end_dadateконец договора, может быть NULL

Пример: данные

work_modes · 4 строки

tab_numstart_datefinish_datewplace_typed1d2d3d4d5end_da
10012025-08-012025-09-09111001NULL
10012025-09-109999-12-311111112025-09-11
10022025-08-259999-12-31210101NULL
10032025-09-082025-09-30101110NULL

Ожидаемый ответ

tab_numdayto_be_at_office
10012025-09-011
10012025-09-021
10012025-09-030
10012025-09-040
10012025-09-051
10012025-09-06NULL
10012025-09-07NULL
10012025-09-081
10012025-09-091
10012025-09-101
10012025-09-111
10012025-09-12NULL
10012025-09-13NULL
10012025-09-14NULL
10022025-09-010
10022025-09-020
10022025-09-030
10022025-09-040
10022025-09-050
10022025-09-06NULL
10022025-09-07NULL
10022025-09-081
10022025-09-090
10022025-09-101
10022025-09-110
10022025-09-121
10022025-09-13NULL
10022025-09-14NULL
10032025-09-01NULL
10032025-09-02NULL
10032025-09-03NULL
10032025-09-04NULL
10032025-09-05NULL
10032025-09-06NULL
10032025-09-07NULL
10032025-09-080
10032025-09-091
10032025-09-101
10032025-09-111
10032025-09-120
10032025-09-13NULL
10032025-09-14NULL
Как проверяем Ваш запрос выполняется в PostgreSQL 16 прямо в браузере на 5 наборах данных: пример выше и скрытые — с NULL, повторами и пустыми таблицами. Нужен один SELECT, можно с WITH. Сравниваем значения по порядку колонок, названия колонок могут быть свои. Порядок строк важен — как задано в условии.
tab_num, day, to_be_at_office
датыLEFT JOINNULLусловная агрегация

Источник: тестовое инженера данных в Сбере, сборник No Data No Growth. Условие пересказано своими словами.