Последний день месяца и последний момент этого дня — разные границы. Разбираем, как описать отчётный период словами и проверить соседние интервалы.
Название месяца ещё не задаёт точный отбор
Представим условный отчёт службы доставки за октябрь. В задании написано «по 31 октября», и заказ, завершённый вечером этого дня, должен попасть в итог. Но если при обработке границей стало начало 31 октября, почти весь последний день окажется за пределами выбранного периода. Название отчёта останется правильным, а состав записей — другим.
Здесь важен не только формат даты, но и правило включения границы. Календарная дата обозначает день, а событие может иметь часы, минуты и доли секунды. Различие между датой и моментом события полезно разобрать заранее. Для отчётного периода нужен следующий шаг: договориться, какие именно моменты входят в выбранный месяц.
Граница может входить в период или оставаться снаружи
В документации PostgreSQL о диапазонах отдельно описаны включаемые и исключаемые границы. Если граница включается, значение ровно на ней принадлежит диапазону. Если исключается — не принадлежит. Это понятие можно обсудить без запросов к базе: что делать с доставкой, зарегистрированной ровно в начале следующего месяца?
Для нашего отчёта выберем правило: от начала октября включительно до начала ноября, не включая это начало. Тогда весь октябрь относится к одному периоду, а момент начала ноября — к следующему. Это предлагаемая договорённость для условного примера, а не обязательное правило любого отчёта. Главное — одинаково применять выбранный смысл во всей цепочке обработки.
Не нужно угадывать последнюю долю секунды
Попытка завершить период «самым последним временем» последнего дня зависит от подробности хранения. В описании типов времени PostgreSQL временные отметки могут содержать доли секунды. Поэтому последнее видимое на экране целое значение секунд не обязательно является последним возможным моментом, который хранится в данных.
В нашей договорённости удобнее назвать начало следующего периода и исключить его. Тогда не приходится отдельно придумывать окончание для каждой поддерживаемой подробности времени. При этом исходные записи нельзя округлять задним числом ради красивой границы: такое изменение способно переместить событие между месяцами. Сначала согласуют правило отбора, затем проверяют его применение к сохранённым значениям.
Соседние периоды должны стыковаться
Проверим условную доставку на стыке двух месяцев. Октябрьский отчёт её не включает, если момент равен началу ноября. Ноябрьский включает, поскольку его начало принято включаемым. В такой паре один момент получает одно место. Если оба отчёта включают общую границу, запись может повториться; если оба исключают — потеряться между ними.
Для учебной проверки достаточно нескольких вымышленных событий: в начале октября, в середине месяца, перед началом ноября и ровно на ноябрьской границе. Для каждого заранее запишем ожидаемый период. Затем сравним отбор с этим списком. Проверка только общей суммы может не заметить две ошибки, которые случайно компенсировали друг друга.
Нужно согласовать и календарь, и смысл события
Начало месяца следует понимать в выбранном временном контексте. Если одна система использует местное время подразделения, а другая трактует тот же день иначе, одинаковые подписи границ не гарантируют одинакового отбора. Вопрос подробно разобран в статье о часовых поясах в отчётах. Здесь достаточно зафиксировать один согласованный календарь для рассматриваемого результата.
Кроме того, дата создания заказа, его оплаты и доставки отвечают на разные вопросы. Для нашего отчёта выбираем именно завершение доставки. Исправление последней минуты не поможет, если обработка отбирает другое событие. Первое описание периода должно называть и временную границу, и поле, смысл которого команда понимает одинаково.
Что передать специалисту перед расчётом
Сформулируйте период обычными словами: какое событие считаем, где начинается интервал, входит ли начало, где заканчивается и входит ли конец. Добавьте выбранный временной контекст и несколько пограничных примеров. Такое задание легче проверить, чем просьбу «взять все записи за месяц», в которой важные решения оставлены исполнителю.
Сам язык работы с таблицами объясняет введение в SQL. Продолжить изучение отбора и интерпретации данных можно на программе «SQL инженер». Полезный результат первого обсуждения — однозначно определить судьбу события ровно на границе двух отчётов.


