Выборка всех дат между двумя промежутками в MySQL

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы сформировать список дат между двумя определенными значениями, вы можете воспользоваться рекурсивным CTE в MySQL следующим образом:

SQL
Скопировать код
WITH RECURSIVE DateSeries AS (
  SELECT '2023-01-01' AS target_date -- стартовая дата – Новый Год
  UNION ALL
  SELECT target_date + INTERVAL 1 DAY FROM DateSeries
  WHERE target_date < '2023-01-10' -- указываем дату окончания
)
SELECT target_date FROM DateSeries;

Замените даты '2023-01-01' и '2023-01-10' на те, которые вас интересуют.

Кинга Идем в IT: пошаговый план для смены профессии

Исследуем подробнее: генерация более широкого диапазона дней

Приведенный выше пример использует рекурсивный CTE, доступный начиная с MySQL 8.0. Это удобный способ итерировать даты. Если нужен более длительный период, достаточно изменить размер интервала.

Если вы работаете с более ранней версией MySQL, воспользуйтесь числовой последовательностью или календарной таблицей. Пример запроса для такого случая:

SQL
Скопировать код
SELECT DATE_ADD('2023-01-01', INTERVAL a.i + 10 * b.i + 100 * c.i DAY) AS Date
FROM (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) a
JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) b
JOIN (SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) c
WHERE DATE_ADD('2023-01-01', INTERVAL a.i + 10 * b.i + 100 * c.i DAY) BETWEEN '2023-01-01' AND '2023-12-31'
ORDER BY Date;

Следим за бесконечными циклами при помощи MAX_RECURSION

Рекурсивные запросы могут зациклиться, чтобы этого избежать, используйте ограничение MAX_RECURSION.

Для генерации большого количества дат удобно использовать предварительно заполненную таблицу. Это можно сравнить с песочными часами, в которых готовый песок уже есть в наличии.

Учет високосных лет и временных зон

Учет високосных лет и разных временных зон – важный момент для получения точных результатов запросов, немного похожий на жонглирование: все обязательно должно находиться в движении и в балансе.

Визуализация

Вы можете представить процесс поиска дат в диапазоне между двуми календарными точками как ловлю рыбы между двумя буями:

Markdown
Скопировать код
Буй-старт 🚩: 1 апреля
Буй-финиш 🏁: 10 апреля

Поиск дат напоминает 🎣 рыбалку:

Markdown
Скопировать код
🚩🎣🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🏁
# Каждая 🐟 обозначает одну найденную дату. Чем больше 🐟, тем богаче набор данных!

Считайте SQL вашей сетью, которой вы аккуратно собираете требуемые дни.

Индивидуализация запроса: Ваши уникальные требования

Возможности написания SQL-запросов так же многообразны, как и люди. Если вам необходимы только рабочие дни или исключить определенные праздники, вы можете настроить свой рекурсивный CTE или использовать JOIN с дополнительными таблицами для этого.

Оптимизация производительности: Эффективность – прежде всего!

Для оптимизации производительности важно предварительно сгенерировать данные и корректно их проиндексировать. Этот аспект особенно критичен при работе с большим объемом данных.

Работа с большими диапазонами дат: стратегия подзапросов и соединений

При обработке больших диапазонов дат вспомогательные подзапросы и кросс-джойны будут неоценимым инструментом. Не забудьте о правильной индексации и методах разбиения данных с целью улучшения производительности.

Полезные материалы

  1. MySQL :: MySQL 8.0 Справочное руководство :: 14.7 Функции даты и времени — подробно о функциях даты и времени в MySQL.
  2. sql – generate days from date range — обсуждение методов генерации дат в MySQL.
  3. MySQL – Оператор Between — разъяснение работы оператора BETWEEN в MySQL.
  4. Оператор SQL BETWEEN — руководство по использованию оператора SQL BETWEEN.