Серии подряд идущих дней
Контекст
Финал разбора журнала: вместо отдельных дат руководителю нужны отрезки непрерывной работы — с какого по какое число человек выходил без единого пропуска и сколько это дней. Одна и та же таблица отметок, но смотреть на неё надо не по строкам, а по цепочкам.
Задача
Верните все серии подряд идущих дней с отметкой по каждому сотруднику: начало, конец и длину серии.
Данные
Таблица attendance — отметки присутствия (одна строка = один день):
| колонка | тип | что хранит |
|---|---|---|
employee_id | int | номер сотрудника, ссылка на employees.id |
work_day | date | день, когда сотрудник отметился |
Таблица employees — сотрудники: id, name, department_id, manager_id, job_title, salary, hired_at, left_at.
Примерные строки attendance (сотрудник 3):
| employee_id | work_day |
|---|---|
| 3 | 2026-06-08 |
| 3 | 2026-06-09 |
| 3 | 2026-06-12 |
Правила
- Колонки:
employee(имя),started_at,ended_at,length. - Серия — это дни одного сотрудника, идущие подряд без пропусков. Первый же пропущенный день серию обрывает, и следующая начинается заново.
length— сколько дней в серии; оба конца считаются. Одна отметка даёт серию длиной 1, где начало и конец совпадают.- Серии считаются внутри одного сотрудника: одинаковые дни у разных людей — это разные серии.
- Сортировка:
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: данные и ожидаемый результат
Таблицы и данные
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
department_id INTEGER NOT NULL,
manager_id INTEGER,
job_title TEXT NOT NULL,
salary INTEGER,
hired_at DATE NOT NULL,
left_at DATE
);
CREATE TABLE attendance (
employee_id INTEGER NOT NULL,
work_day DATE NOT NULL,
PRIMARY KEY (employee_id, work_day)
);
INSERT INTO employees
(id, name, department_id, manager_id, job_title, salary, hired_at, left_at)
VALUES
(1, 'Анна', 1, NULL, 'Инженер', 200000, DATE '2024-01-01', NULL),
(2, 'Борис', 1, NULL, 'Аналитик', 210000, DATE '2024-02-01', NULL);
INSERT INTO attendance (employee_id, work_day) VALUES
(1, DATE '2026-02-01'),
(1, DATE '2026-02-02'),
(1, DATE '2026-02-04'),
(2, DATE '2026-02-01'),
(2, DATE '2026-02-02'),
(2, DATE '2026-02-03'); | employee | started_at | ended_at | length |
|---|---|---|---|
| Анна | 2026-02-01 | 2026-02-02 | 2 |
| Борис | 2026-02-01 | 2026-02-03 | 3 |
| Анна | 2026-02-04 | 2026-02-04 | 1 |