我有一个名为opening_hours的表,如下所示:
id int(11),weekday int(1),start_hour time,end_hour time
我使用此查询选择现在打开的所有商店:
SELECT * FROM shops s
INNER JOIN opening_hours o
ON ( s.id = o.id )
AND ( o.weekday = WEEKDAY(CURDATE()) + 1 )
AND ( ( CURTIME() >= o.start_hour ) AND ( CURTIME() <= o.end_hour ) )
我的问题是,当商店在午夜之后营业时,此查询会给出错误的结果。那是因为午夜之后的时间早于午夜之前的时间。如何处理?
答案 0 :(得分:2)
当end_hour
小于start_hour
时,您必须修改end_hour
,使其大于start_hour
。
实现此目的的一种方法是在end_hour
小于24:00:00
时从end_hour
中扣除start_hour
,否则end_hour
占优势。
SELECT * FROM shops s
INNER JOIN opening_hours o
ON ( s.id = o.id )
AND ( o.weekday = WEEKDAY(CURDATE()) + 1 )
AND ( ( CURTIME() >= o.start_hour ) AND ( CURTIME() <= IF(o.end_hour < o.start_hour,TIMEDIFF(TIME('24:00:00'),o.end_hour),o.end_hour ) ) ) ;
修改强>
当end_hour
为00:00:00
时,上述查询效果很好。
但是这种情况可能会给出错误的输出
start_hour = 07:00:00 & end_hour = 02:00:00
。
所以,在这里你可以恢复(在主查询中使用这个条件):
AND
(
IF(o.end_hour < o.start_hour,
( CURTIME() >= o.start_hour ) OR ( CURTIME() <= o.end_hour ),
( CURTIME() >= o.start_hour ) AND ( CURTIME() <= o.end_hour )
)
请注意,如果范围位于同一日期,则应以此条件为准:
( CURTIME() >= o.start_hour ) AND ( CURTIME() <= o.end_hour )
。
如果范围包裹午夜,那么这个条件应该在行动中:
( CURTIME() >= o.start_hour ) OR ( CURTIME() <= o.end_hour )
答案 1 :(得分:2)
正确的逻辑更复杂。当开放时间跨越两个日期时,那么在凌晨时分,您必须查看之前的天开放时间 - 除非您假设每天的小时数相同(但是那为什么要有桌子?)。
条件更像是这样:
SELECT *
FROM shops s INNER JOIN
opening_hours o
ON s.id = o.id
WHERE ((o.weekday = weekday(curdate()) + 1) and
((o.end_hour > o.start_hour and curtime() >= o.start_hour and curtime <= o.end_hour) or
(o.end_hour < o.start_hour and curtime() >= o.start_hour)
) or
(o.weekday = weekday(date_add(curdate(), interval 1 day)) + 1 and
o.end_hour < o.start_hour and
curtime() <= o.end_Hour
);
这三个条件是: