Случайные значения datetime в указанном диапазоне MySQL
Быстрый ответ
Если требуется добавить в таблицу случайную дату и время в предложенном диапазоне, используйте функции RAND()
и TIMESTAMPADD
. Необходимо сгенерировать случайное число секунд и добавить их к начальной дате. Пример такого запроса:
INSERT INTO table_name (datetime_column) VALUES (TIMESTAMPADD(SECOND, FLOOR(RAND() * TIMESTAMPDIFF(SECOND, '2021-01-01', '2021-12-31')), '2021-01-01'));
Не забывайте заменить название своей таблицы, название столбца с датой и временем, а также указать необходимый вам диапазон дат.
Достижение настоящей случайности
Для обеспечения равного шанса выбора любой даты и времени в заданном диапазоне используйте функции FROM_UNIXTIME
и UNIX_TIMESTAMP
. С их помощью можно преобразовать даты в количество секунд, прошедших с начала эпохи Unix, и обратно. Это позволит исключить смещение вероятности:
INSERT INTO table_name (datetime_column)
VALUES (FROM_UNIXTIME(
UNIX_TIMESTAMP('2021-01-01') +
FLOOR(RAND() * (UNIX_TIMESTAMP('2021-12-31') – UNIX_TIMESTAMP('2021-01-01') + 1))
));
Проверьте корректность генерации случайных дат, особенно при работе с високосными годами. Подгоните диапазон дат под свои нужды.
Ограничения внутри аномалий
Чтобы убедиться, что ваши сгенерированные случайные даты всегда попадают в заданный бизнес-диапазон, добавьте дополнительную проверку:
SET @startDate = '2021-01-01 00:00:00', @endDate = '2021-12-31 23:59:59';
INSERT INTO table_name (datetime_column)
SELECT * FROM (
SELECT TIMESTAMPADD(SECOND, FLOOR(RAND() * TIMESTAMPDIFF(SECOND, @startDate, @endDate)), @startDate) AS random_date
) AS subquery
WHERE random_date BETWEEN @startDate AND @endDate;
Этот подзапрос с условием WHERE отфильтрует даты, выходящие за рамки установленного диапазона из-за округления или других аномалий.
Визуализация
Предположим, вам нужно разместить случайно выбранную книгу на книжной полке, организованной по алфавиту, где диапазон расположения книг – от А до Я:
Диапазон книжной полки: [1 января 2021 года, ..., 31 декабря 2021 года]
Ваш SQL-запрос в данном случае будет действовать как библиотекарь, который вставляет книгу в заданный интервал:
INSERT INTO library (random_date)
VALUES (RAND() between '1 января 2021 года' and '31 декабря 2021 года');
В итоге мы получаем следующее:
До: [📖,📖,📖,📖] После: [📖,📖,⭐️📖,📖]
Здесь звездочка ⭐️ обозначает новую книгу, случайно вставленную в пределах указанного диапазона.
Адаптация стратегий распределения
Если нужно контролировать распределение дат и времени, вы можете скорректировать их генерацию следующим образом:
INSERT INTO table_name (datetime_column)
VALUES (
TIMESTAMPADD(SECOND,
FLOOR(
RAND() * 1 + -- добавляем немного случайности
CASE DAYOFWEEK(CURDATE())
WHEN 2 THEN 100 -- увеличиваем вероятность понедельников
ELSE 0
END
),
@startDate)
);
Для особого внимания к определенным дням или времени подстройте логику внутри условного оператора.
Оптимизация значительных операций
Когда работаете с большим объемом данных и нужно быстро добавить множество случайных дат, использование переменных может быть полезно:
SET @diff = TIMESTAMPDIFF(SECOND, @startDate, @endDate);
SET @randomSeconds = FLOOR(RAND() * (@diff + 1));
INSERT INTO table_name (datetime_column)
VALUES (TIMESTAMPADD(SECOND, @randomSeconds, @startDate));
Выполнение вычислений вне INSERT
может ускорить процесс, подобно тому, как подкрепление перед марафоном может ускорить время его прохождения.
Полезные материалы
- Руководство по MySQL 8.0 – Функции даты и времени — подробное описание функции TIMESTAMPADD.
- Руководство по MySQL 8.0 – Математические функции — описание и принцип работы функции RAND.
- Stack Overflow: генерация случайных дат в JavaScript — советы по созданию случайных дат.
- Руководство по MySQL 8.0 – Оператор INSERT — документация команды вставки INSERT в MySQL.
- Руководство по MySQL 8.0 – Типы данных DATE, DATETIME и TIMESTAMP — описание типов данных даты и времени в MySQL.