Столкнулся с ситуацией, когда посредством MySQL необходимо выбрать непрерывный диапазон дат. Казалось бы, что тут сложного? А вот что – в целевой таблице может не быть данных за какую-то из дат в диапазоне. Соответственно непрерывный диапазон не получается.
Решений наверное может быть много разных. Предлагаю ознакомиться с одним из них.
Для удобства использования, решение будет завернуто в процедуру MySQL.
Итак, задача такова: получить непрерывную последовательность прошедших дат, заданной длинны, начиная от текущей даты (не включая ее).
Решение:
CREATE DEFINER = 'root'@'localhost' PROCEDURE `dates_from_now`(IN max_recs INTEGER(11)) NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE cur_dt DATETIME; DECLARE numrecs INT DEFAULT 0; # Локаль модифицируем чтобы даты отображать в кирилице SET lc_time_names = 'ru_RU'; # Создаем небольшую табличку в памяти DROP TABLE IF EXISTS dates; CREATE TABLE dates ( id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, dt DATETIME NOT NULL ) ENGINE=HEAP; # Заполняем табличку WHILE numrecs < max_recs DO INSERT INTO dates (dt) VALUES ( DATE_FORMAT( NOW() - INTERVAL numrecs + 1 DAY, '%Y-%m-%d 00:00:00' ) ); SELECT COUNT(*) INTO numrecs FROM dates; END WHILE; # Выбираем и форматируем даты SELECT DATE_FORMAT( dt, '%d %b' ) as date FROM dates ORDER BY dt; END;
Этот нехитрый код решает указанную проблему.
mysql> call dates_from_now(14); +-----------+ | date | +-----------+ | 27 Окт | | 28 Окт | | 29 Окт | | 30 Окт | | 31 Окт | | 01 Ноя | | 02 Ноя | | 03 Ноя | | 04 Ноя | | 05 Ноя | | 06 Ноя | | 07 Ноя | | 08 Ноя | | 09 Ноя | +-----------+ 14 rows in set (0.03 sec) Query OK, 0 rows affected (0.03 sec)
Для повседневных нужд подходит, как поведет себя в бою – посмотрим, потестируем.
Собственно статья-подсказка тут http://datacharmer.blogspot.com/2006/06/filling-test-tables-quickly.html, если руки дойдут, переведу ее полностью, т.к. тема заполнения таблиц тестовыми данными нужная и важная.
Enjoy 😉
cur_dt не нужна
И лишний запрос “SELECT COUNT(*) INTO numrecs FROM dates;” можно заменить на “SET numrecs = numrecs + 1;”