Я писал мини-планировщик, выполняющий определенную задачу. Для расчета времени срабатывания я использую MYSQL. Я застрял в написании одного из запросов.

Найдите немедленное DateTime, которое больше, чем заданное предыдущее время,

А ТАКЖЕ

День требуемой немедленной даты и времени должен быть ЛЮБЫМ из заданных дней

А ТАКЖЕ

Time(HH:MM:SS) часть требуемой немедленной даты и времени должна быть равна заданному времени.

Примеры:

(а)

Если указаны дни ('ПН', 'СРЕДА', 'СБ'),

Указано время 10:15:00,

Данное предыдущее время 2014-11-12 23:17:00

Затем MYSQL должен вернуться 2014-11-15 10:15:00

( Б)

Указанные дни: («ВС», «СБ», «ВТ»)

Дано Время: 09:10:00

Предыдущее время 2014-11-30 07:05:12

MYSQL должен вернуть 2014-11-30 09:10:00

(c)

Указанные дни: («ПН», «ЧТ», «СБ»)

Дано Время: 11:00:00

Данное предыдущее время 2014-12-29 11:55:12

MYSQL должен вернуть 2015-01-01 11:00:00

(d) Дни: (ВС, ЧТ, СБ)'

Данное предыдущее время 2014-02-27 18:15:00

Дано Время 15:15:00

Результат запроса MYSQL: 2014-03-01 15:15:00

(е)

ДНИ: (ВТ, СР, ПТ)

Предыдущая дата: 2014-12-23 09:30:00

Время : 08:00:00

Ожидаемый результат:

2014-12-24 08:00:00

(е)

ДНИ: ВС, ВТ, ЧТ

Предыдущая дата: 2014-07-31 10:10:00

Время: 06:07:08

Ожидаемое разрешение: 2014-08-03 06:07:08

0
Ritesh Kumar Gupta 12 Ноя 2014 в 20:55
Какой язык программирования вы используете? Я думаю, что это не mysql-задача.
 – 
dognose
12 Ноя 2014 в 21:18
Я пытаюсь использовать запрос MYSQL.
 – 
Ritesh Kumar Gupta
12 Ноя 2014 в 21:20

2 ответа

Используя числовые номера дней недели, 0 = понедельник, 6 = воскресенье:

set @day1=0;
set @day2=2;
set @day3=5;
set @time=time('10:15:00');
set @prevtime=timestamp('2014-11-12 23:17:00');

select if(weekday(@nexttime:=date_add(concat(date(@prevtime),' ',@time),interval if(@time>time(@prevtime),0,1) day)) in (@day1,@day2,@day3),@nexttime,if(weekday(@nexttime:=date_add(@nexttime,interval 1 day)) in (@day1,@day2,@day3),@nexttime,if(weekday(@nexttime:=date_add(@nexttime,interval 1 day)) in (@day1,@day2,@day3),@nexttime,if(weekday(@nexttime:=date_add(@nexttime,interval 1 day)) in (@day1,@day2,@day3),@nexttime,if(weekday(@nexttime:=date_add(@nexttime,interval 1 day)) in (@day1,@day2,@day3),@nexttime,if(weekday(@nexttime:=date_add(@nexttime,interval 1 day)) in (@day1,@day2,@day3),@nexttime,date_add(@nexttime,interval 1 day))))))) as nexttime;

Если у вас есть только один день недели, вы можете установить для всех трех переменных одно и то же число.

1
ysth 20 Ноя 2014 в 15:56
Он возвращает неправильное значение для следующих случаев: SET @day1='2'; SET @time=TIME('05:15:00'); SET @prevtime=TIMESTAMP('2014-11-20 06:57:27 '); SELECT IF(WEEKDAY(@nexttime:=DATE_ADD(CONCAT(DATE(@prevtime),' ',@time),INTERVAL IF(@time>TIME(@prevtime),0,1) DAY)) IN (@day1),@nexttime,IF(WEEKDAY(@nexttime:=DATE_ADD(@nexttime,INTERVAL 1 DAY)) IN (@day1),@nexttime,IF(WEEKDAY(@nexttime:=DATE_ADD(@nexttime,INTERVAL 1 DAY)) IN (@day1),@nexttime,IF(WEEKDAY(@nexttime:=DATE_ADD(@nexttime,INTERVAL 1 DAY)) IN (@day1),@nexttime,DATE_ADD(@nexttime,INTERVAL 1 DAY))))) AS nexttime;
 – 
Ritesh Kumar Gupta
20 Ноя 2014 в 14:56
Случай 2: SET @day1='3'; SET @time=TIME('05:15:00'); SET @prevtime=TIMESTAMP('2014-11-20 06:57:27'); SELECT IF(WEEKDAY(@nexttime:=DATE_ADD(CONCAT(DATE(@prevtime),' ',@time),INTERVAL IF(@time>TIME(@prevtime),0,1) DAY)) IN (@day1),@nexttime,IF(WEEKDAY(@nexttime:=DATE_ADD(@nexttime,INTERVAL 1 DAY)) IN (@day1),@nexttime,IF(WEEKDAY(@nexttime:=DATE_ADD(@nexttime,INTERVAL 1 DAY)) IN (@day1),@nexttime,IF(WEEKDAY(@nexttime:=DATE_ADD(@nexttime,INTERVAL 1 DAY)) IN (@day1),@nexttime,DATE_ADD(@nexttime,INTERVAL 1 DAY))))) AS nexttime;
 – 
Ritesh Kumar Gupta
20 Ноя 2014 в 14:57
Для случаев 1 и 2: 2014-11-26 05:15:00 и 2014-11-27 05:15:00 соответственно являются правильными значениями.
 – 
Ritesh Kumar Gupta
20 Ноя 2014 в 15:08
Я предполагал три разных дня; для работы только с одним требуется небольшое изменение. Будет редактировать.
 – 
ysth
20 Ноя 2014 в 15:50
Ok. Спасибо за быстрый ответ. Если выбран 1 день, я могу установить @day1=@day2=@day3=selected_numericVal, и он вернет ожидаемое значение. Теперь, если выбрано 2 дня, то возвращается неверное значение. Только запрос работает хорошо, если число выбранных дней >=3.
 – 
Ritesh Kumar Gupta
21 Ноя 2014 в 09:59

Вы должны быть в состоянии сформулировать предложение where, используя функции DAYNAME(), HOUR(), MINUTE() и SECOND(): https://dev.mysql.com/doc /refman/5.5/en/date-and-time-functions.html

Если производительность недостаточна, и вы начинаете желать, чтобы можно было индексировать, например, DAYNAME(columname), вы можете рассмотреть возможность денормализации ваших данных и сохранения значения DAYNAME отдельно. Однако в этот момент может быть проще переключиться на Postgres: http://www.postgresql.org/docs/9.1/static/indexes -expressional.html

0
Szocske 13 Ноя 2014 в 00:05