У меня есть такая таблица. Он показывает время начала и окончания работы различных ресторанов в разные дни недели.
Я хочу вот что. Учитывая текущее время, код должен отображать, какой ресторан открыт в данный момент. Это то, что я пробовал.
(CASE WHEN user_time.start_time > user_time.end_time AND ( CURTIME() < user_time.end_time OR CURTIME() > user_time.start_time ) THEN 1
WHEN user_time.start_time < user_time.end_time AND ( CURTIME() > user_time.start_time AND CURTIME() < user_time.end_time ) THEN 1
ELSE 0
END) = 0 AND user_time.weekday = WEEKDAY(CURDATE())
Он находит текущий день недели и соответствующее время открытия и окончания для сравнения с текущим временем. Но проблема возникает, когда ресторан открывается вечером и заканчивается на следующий день.
Это означает, что запрос должен иметь возможность решить, какие данные о времени использовать, сегодняшние или вчерашние. Пожалуйста, помогите мне найти решение.
Версия сервера MySQL — 10.4.17 MariaDB.
Тип данных No — int, все остальное — VARCHAR.
Но проблема возникает, когда ресторан открывается вечером и заканчивается на следующий день. Преобразуйте значение времени в числовое и добавьте 240000
к Endtime
, когда Starttime+0 > Endtime+0
.
Спасибо, Акина. Это было полезно. Но давайте предположим, что сейчас четверг, 7 утра. Согласно таблице, ресторан А все еще открыт, но добавление 24 часов к времени окончания четверга не поможет найти это.
@CharlieSchwab - можете опубликовать рисунок таблицы, чтобы увидеть типы данных. я видел, что также неправильное время в таблице. 24:00 неверно. Только 23:59:59 или 00:00:00. я знаю, что это не главная проблема
Я подозреваю, что вы используете MariaDB
Вы можете разделить на 2 строки каждую строку, содержащую Endtime
следующего дня:
WITH cte AS (
SELECT *, Weekday day, Starttime time1, Endtime time2 FROM user_time
WHERE Starttime < Endtime
UNION ALL
SELECT *, Weekday, Starttime, '23:59' FROM user_time
WHERE Starttime > Endtime
UNION ALL
SELECT *,
DATE_FORMAT((STR_TO_DATE(CONCAT(LEFT(CURRENT_DATE, 8), Weekday), '%X-%V-%W') + INTERVAL 1 DAY), '%a'),
'00:00', Endtime
FROM user_time
WHERE Starttime > Endtime
)
SELECT No, Restaurant, Weekday, Starttime, Endtime
FROM cte
WHERE day = DATE_FORMAT(CURRENT_DATE, '%a')
AND NOW() BETWEEN CONCAT(CURRENT_DATE, ' ', time1, ':00') AND CONCAT(CURRENT_DATE, ' ', time2, ':00')
Смотрите демо.
это не работает - ГДЕ день недели = DATE_FORMAT (CURRENT_DATE, '%a') будет генерировать день текущей даты, и если он позже 00:00 в столбце День недели был днем вчера
@ forpas - я изменил ваш отчет, так что также должна быть выбрана строка № 9. Проблема в том, что день начала вчера, а время начала вчера больше, чем время начала сегодня. см. dbfiddle.uk/…
@BerndBuffen, вот почему в этом случае: время начала> время окончания, я разделяю строку на 2 строки, поэтому, если строка ('9', 'B', 'Вт', '22:00', '21:00' ) делится на ('9', 'Ч', 'Вт', '22:00', '23:59') и ('9', 'Ч', 'Ср', '00:00', «21:00»).
о, о, о, моя ошибка!!! вы правы на 100%. ИЗВИНИТЕ.. Я уверен, что я уже в рождественской моде. - проголосовать за
Я построил таблицу с двумя новыми виртуальными полями. Эти поля заполняются автоматически. Я использую небольшую хитрость для буднего дня. Итак, я генерирую дату, а день недели - это день месяца. Он используется только для сравнения.
SELECT *
FROM user_time
WHERE
TIMESTAMP(CONCAT('2000-01-0',DAYOFWEEK(CURDATE()),' ',current_time()))
BETWEEN date_start AND date_end
OR
IF(DAYOFWEEK(CURDATE()) <> 'SUNDAY' , FALSE,
TIMESTAMP(CONCAT('2000-01-0',DAYOFWEEK(CURDATE())+7,' ',current_time()))
BETWEEN date_start AND date_end
);
Таблица
CREATE TABLE `user_time` (
`No` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Restaurant` varchar(32) DEFAULT NULL,
`Weekday` enum('SUNDAY','MONDAY','TUESDAY','WEDNESDAY','THURSDAY','FRIDAY','SATURDAY') DEFAULT NULL,
`start_time` varchar(5) DEFAULT NULL,
`end_time` varchar(5) DEFAULT NULL,
`date_start` timestamp GENERATED ALWAYS AS (cast(concat('2000-01-0',`Weekday` + 0,' ',`start_time`) as datetime)) STORED,
`date_end` timestamp GENERATED ALWAYS AS (cast(concat('2000-01-0',`Weekday` + 0,' ',`end_time`) + interval if (cast(`start_time` as time) >= cast(`end_time` as time),1,0) day as datetime)) STORED,
PRIMARY KEY (`No`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
вставьте некоторые данные
INSERT INTO `user_time` (`No`, `Restaurant`, `Weekday`, `start_time`, `end_time`)
VALUES
(1, 'a', 'MONDAY', '12:00', '13:00'),
(2, 'a', 'MONDAY', '14:00', '02:00'),
(3, 'b', 'MONDAY', '16:00', '18:00'),
(4, 'c', 'TUESDAY','21:00', '18:00');
посмотреть, что сгенерировано
MariaDB [bernd]> SELECT * FROM user_time;
+----+------------+---------+------------+----------+---------------------+---------------------+
| No | Restaurant | Weekday | start_time | end_time | date_start | date_end |
+----+------------+---------+------------+----------+---------------------+---------------------+
| 1 | a | MONDAY | 12:00 | 13:00 | 2000-01-02 12:00:00 | 2000-01-02 13:00:00 |
| 2 | a | MONDAY | 14:00 | 02:00 | 2000-01-02 14:00:00 | 2000-01-03 02:00:00 |
| 3 | b | MONDAY | 16:00 | 18:00 | 2000-01-02 16:00:00 | 2000-01-02 18:00:00 |
| 4 | c | TUESDAY | 21:00 | 18:00 | 2000-01-03 21:00:00 | 2000-01-04 18:00:00 |
+----+------------+---------+------------+----------+---------------------+---------------------+
4 rows in set (0.01 sec)
MariaDB [bernd]>
запросить текущую дату
MariaDB [bernd]> SELECT *
-> FROM user_time
-> WHERE
-> TIMESTAMP(CONCAT('2000-01-0',DAYOFWEEK(CURDATE()),' ',current_time()))
-> BETWEEN date_start AND date_end;
+----+------------+---------+------------+----------+---------------------+---------------------+
| No | Restaurant | Weekday | start_time | end_time | date_start | date_end |
+----+------------+---------+------------+----------+---------------------+---------------------+
| 4 | c | TUESDAY | 21:00 | 18:00 | 2000-01-03 21:00:00 | 2000-01-04 18:00:00 |
+----+------------+---------+------------+----------+---------------------+---------------------+
1 row in set (0.00 sec)
MariaDB [bernd]>
Спасибо за глубокое исследование моей проблемы. Думаю, это решит первую проблему. Но как насчет второй проблемы? Что, если ресторан "а" открывается в 21:00 воскресенья и заканчивается в 11:00 понедельника? Если текущее время — 10:00 понедельника, ресторан «а» должен появиться открытым.
Это также работает. см. строку № 4. он открывается во ВТОРНИК в 21:00 и закрывается в СРЕДУ в 18:00. Сегодня СРЕДА, и он был выбран в моем запросе
Я имею в виду воскресенье 07.01.2000, верно? И понедельник 2000-01-01. Итак, как запрос может выбирать между воскресеньем и следующим понедельником?
я изменил первый запрос, но не тестировал
не могли бы вы опубликовать тип данных каждого поля и версию вашего сервера MySQL