sql solution.sql

Серии подряд идущих дней в SQL

Превратите отдельные отметки присутствия в непрерывные интервалы с началом, концом и длиной.

  • ЯзыкSQL
  • УровеньПродвинутый
  • НавыкGaps and Islands и оконные функции

Серии подряд идущих дней

Контекст

Финал разбора журнала: вместо отдельных дат руководителю нужны отрезки непрерывной работы — с какого по какое число человек выходил без единого пропуска и сколько это дней. Одна и та же таблица отметок, но смотреть на неё надо не по строкам, а по цепочкам.

Задача

Верните все серии подряд идущих дней с отметкой по каждому сотруднику: начало, конец и длину серии.

Данные

Таблица attendance — отметки присутствия (одна строка = один день):

колонкатипчто хранит
employee_idintномер сотрудника, ссылка на employees.id
work_daydateдень, когда сотрудник отметился

Таблица employees — сотрудники: id, name, department_id, manager_id, job_title, salary, hired_at, left_at.

Примерные строки attendance (сотрудник 3):

employee_idwork_day
32026-06-08
32026-06-09
32026-06-12

Правила

  1. Колонки: employee (имя), started_at, ended_at, length.
  2. Серия — это дни одного сотрудника, идущие подряд без пропусков. Первый же пропущенный день серию обрывает, и следующая начинается заново.
  3. length — сколько дней в серии; оба конца считаются. Одна отметка даёт серию длиной 1, где начало и конец совпадают.
  4. Серии считаются внутри одного сотрудника: одинаковые дни у разных людей — это разные серии.
  5. Сортировка: started_at по возрастанию, при равенстве — имя по алфавиту.

Примеры

-- Выдача на данных «Пульса»:
-- employee       | started_at | ended_at   | length
-- Вика Носова    | 2026-06-01 | 2026-06-14 | 14
-- Данил Крылов   | 2026-06-01 | 2026-06-02 | 2
-- Игорь Соловьёв | 2026-06-01 | 2026-06-09 | 9
-- Настя Ким      | 2026-06-01 | 2026-06-26 | 26
-- Данил Крылов   | 2026-06-04 | 2026-06-15 | 12
-- Игорь Соловьёв | 2026-06-12 | 2026-06-26 | 15
-- Алина Юсупова  | 2026-06-17 | 2026-06-17 | 1
-- Данил Крылов   | 2026-06-18 | 2026-06-26 | 9

-- У Данила Крылова три серии: два дня, потом двенадцать, потом девять.

Где это пригодится

Так считают серии дней активности в подписке, непрерывные периоды работы сервиса и любые «сколько дней подряд». Здесь важно не смешать сотрудников, корректно обработать одиночную отметку и разорвать интервал на первом пропущенном дне.

Двигайтесь по одному шагу

Подсказка 1

Выполняйте расчёт отдельно для каждого сотрудника.

Подсказка 2

Найдите признак, который будет одинаковым у соседних дней одной серии.

Подсказка 3

После группировки посчитайте оба конца интервала и задайте итоговую сортировку.

Как найти непрерывные серии дат

Серия — максимальный непрерывный интервал дат одного сотрудника. Важно не смешать людей и учесть одиночные дни.

Не оставляйте задачу изолированной