选择当前打开的所有商店

时间:2016-07-17 09:59:30

标签: mysql sql database database-design logic

我有一个名为opening_hours的表,如下所示:

id int(11),weekday int(1),start_hour time,end_hour time

enter image description here

我使用此查询选择现在打开的所有商店:

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 ) ) 

我的问题是,当商店在午夜之后营业时,此查询会给出错误的结果。那是因为午夜之后的时间早于午夜之前的时间。如何处理?

2 个答案:

答案 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_hour00: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
      );

这三个条件是:

  • 一天开放时间
  • 开放时间跨度为两天,小时不早于开头
  • 营业时间跨度为两天,小时数早于结束时间