SQL:基于条件的字段值


SQL: field value based on condition?

我需要返回一个特殊值来告诉我当前时间是否在营业时间内:

在表格中位置

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

我需要在查询中返回一个特殊字段:PLACE_IS_OPEN-true或false。

使得当时间为CCD_ 1时返回的结果为:

ID      PLACE_IS_OPEN
1       1
2       1
3       0

这将是一种下降的方式?

测试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

这将返回指定的结果集:

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列是字符数据类型,包含格式化为24小时时钟的字符串。

(注意:使用BETWEEN会在CLOSE的精确分钟上给出错误的结果。14:350将修剪当前时间的秒部分,例如,时间"16:00:45"将被格式化为"16:00",这可能等于指定的CLOSE,但实际上是CLOSE指定的实际时间后45秒。)

您还需要确保没有任何行在午夜"跨越",例如从晚上10点到凌晨2点打开,否则CLOSE的值将小于OPEN。(要使此查询工作,需要将这样一个句点表示为表中的两行,一行从OPEN到"24:00",另一行从"00:00"到CLOSE。)

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

如果您的数据不符合这些规则(例如,关闭的午夜表示为00:00或关闭小于打开,则需要"改进"查询以处理这些条件。


如果OPEN和CLOSE列的数据类型为TIME(而不是字符),则还需要修改查询,使用TIME()函数代替DATE_FORMAT()函数。(此外,在这种情况下,如果允许在当前时间与关闭时间完全匹配时返回值1,则可以使用BETWEEN:当前时间值"16:00:00"将等于关闭时间"16:00:00",因此这实际上取决于在这种情况中是要返回1还是0。

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