2012-07-18 146 views
3

我将需要返回一个特殊值来告诉我,如果当前时间是营业时间内:SQL:基于条件的字段值?

在表地方

ID OPEN  CLOSE 
1  14:00 16:00 
2  12:00 15:00 
3  10:00 14:00 

我需要查询一个特殊的领域返回:PLACE_IS_OPEN - true或false。

,以便到时14:35是返回结果:

ID  PLACE_IS_OPEN 
1  1 
2  1 
3  0 

这将是一个下降的路要走,这件事吗?

回答

5

测试TIME(NOW())位于打开和关闭时间之间并将其布尔结果作为列返回。如果您的OPEN,CLOSE是MySQL DATETIME或TIME列,这将按原样工作

SELECT 
    ID, 
    OPEN, 
    CLOSE, 
    CASE WHEN TIME(NOW()) BETWEEN `OPEN` AND `CLOSE` THEN 1 ELSE 0 END AS PLACE_IS_OPEN 
FROM yourtable 

如果这些字符列,而不是正确的TIME类型,则需要STR_TO_TIME()将它们转换

CASE WHEN TIME(NOW()) BETWEEN TIME(STR_TO_DATE(`OPEN`, '%H:%i')) AND TIME(STR_TO_DATE(`CLOSE`, '%H:%i')) THEN 1 ELSE 0 END AS PLACE_IS_OPEN 

和MySQL应该让你简化CASE声明了,因为BETWEEN将返回0或1,因为它是:

SELECT 
    ID, 
    OPEN, 
    CLOSE, 
    (TIME(NOW()) BETWEEN TIME(STR_TO_DATE(`OPEN`, '%H:%i')) AND TIME(STR_TO_DATE(`CLOSE`, '%H:%i'))) AS PLACE_IS_OPEN 
FROM yourtable 
2

这将返回指定的结果集:

SELECT t.ID 
    , CASE WHEN t.open <= DATE_FORMAT(NOW(),'%H:%i') 
      AND t.close > DATE_FORMAT(NOW(),'%H:%i') 
     THEN 1 ELSE 0 END AS PLACE_IS_OPEN 
    FROM places t 
ORDER BY t.ID 

鉴于OPENCLOSE列是字符数据类型,包含格式化为二十四小时制字符串。 (注意:使用BETWEEN将在CLOSE的精确分钟上给出错误的结果,DATE_FORMAT将修剪当前时间的秒部分,例如,'16:00:45'的时间将会被格式化为'16:00',其可能等于指定的CLOSE,但实际上是由CLOSE指定的实际时间之后的45秒。)

您还需要确保您没有任何行“跨越”午夜,例如开放时间从晚上10点到凌晨2点,其中CLOSE的值将会小于OPEN。 (为了使这个查询起作用,这样的时间段将需要被表示为表中的两个单独的行,从OPEN到'24:00'的一行,以及从'00:00'到CLOSE的另一行。)

请注意,午夜时间的CLOSE需要表示为'24:00'。 (也就是说,24小时开放的地方可以表示为OPEN ='00:00'和CLOSE = '24:00'。)

如果您的数据不符合这些规则(例如,接近被表示为00:00或CLOSE小于OPEN,查询将需要“改进”来处理这些情况。


如果你打开和合拢列数据类型TIME的(而不是字) ,查询也需要修改,使用TIME()函数代替DATE_FORMAT()函数。(此外,在这种情况下,如果在当前时间与关闭时间完全匹配时允许返回值1,则可以使用BETWEEN:当前时间值'16:00:00'将等于CLOSE时间'16:00:00',所以它真的取决于你是否想返回1或0在这种情况下

还要注意NOW()函数将在当前设置的time_zone变量您的(MySQL)会话(因此,该表中的OPEN和CLOSE时间正在被有效地评估,就好像它们是在MySQL会话时区中指定的一样)