使用MySQL CURTIME()& ADDTIME()你如何打击午夜过渡?

时间:2013-11-06 17:40:26

标签: php mysql

我有一张桌子(flightSched),其中包含航班号,航班到达天数,是否到达或离开,最重要的是他们的到达时间,如下图所示。

+-------------+----------------+-----------------+-----------------+
| FlightNo    | don            | depOrArriv      | arrivalTime     | 
+-------------+----------------+-----------------+-----------------+
| ET821       | Daily          | Arrival         | 19:45:24        |
| MS838       | Tuesday        | Arrival         | 00:05:24        |
| H7361       | Tuesday        | Arrival         | 23:15:06        |
+-------------+----------------+-----------------+-----------------+

我想在表格中显示当前时间和当前时间之前四小时之间的所有航班。

在我的查询下面找到

SELECT * 
FROM flightSched
WHERE  `arrivalTime` 
BETWEEN CURTIME() 
AND ADDTIME( CURTIME() ,  '04:00:00' ) 
ORDER BY arrivalTime ASC 
LIMIT 0 , 30

该查询完美无缺,直到航班抵达/离开午夜。根据上表,如果当前时间是21:00:00,则不会显示航班号MS838。 我哪里错了?

有人可以在我的查询中指出我出错的地方吗?

2 个答案:

答案 0 :(得分:1)

我认为这是因为ADDTIME没有按照您的想法行事,请看以下示例:

mysql> SELECT ADDTIME( '19:59:59' ,  '04:00:00' );
+-------------------------------------+
| ADDTIME( '19:59:59' ,  '04:00:00' ) |
+-------------------------------------+
| 23:59:59                            |
+-------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT ADDTIME( '20:00:01' ,  '04:00:00' );
+-------------------------------------+
| ADDTIME( '20:00:01' ,  '04:00:00' ) |
+-------------------------------------+
| 24:00:01                            |
+-------------------------------------+
1 row in set (0.00 sec)

mysql>

一种可能的解决方案是将查询WHERE子句更改为使用TIMEDIFF,然后确保区别在特定范围之间。

如果我们采用一些示例时间值并将TIMEDIFF结果与中午进行比较,我们会得到以下结果:

+----------+---------------------------------+
| time     | TIMEDIFF(MAKETIME(12,0,0),time) |
+----------+---------------------------------+
| 01:00:00 | 11:00:00                        |
| 03:00:00 | 09:00:00                        |
| 05:00:00 | 07:00:00                        |
| 07:00:00 | 05:00:00                        |
| 11:00:00 | 01:00:00                        |
| 13:00:00 | -01:00:00                       |
| 15:00:00 | -03:00:00                       |
| 17:00:00 | -05:00:00                       |
| 19:00:00 | -07:00:00                       |
| 21:00:00 | -09:00:00                       |
| 23:00:00 | -11:00:00                       |
+----------+---------------------------------+

将来的时间导致负时间差(使用显示的顺序提供的参数),因此对于没有缠绕的时间,我们知道-00:00:00和-04:00之间的任何范围:00是可以接受的(根据你提前0到4小时的更新。

因此,为了检查正常没有包装时间,以下内容应该有效:

TIMEDIFF(CURTIME(),arrivalTime)       在MAKETIME(-4,0,0)和MAKETIME(0,0,0)之间

如果我们然后检查包装的值:

+----------+----------------------------------+
| time     | TIMEDIFF(MAKETIME(23,30,0),time) |
+----------+----------------------------------+
| 01:00:00 | 22:30:00                         |
| 03:00:00 | 20:30:00                         |
| 05:00:00 | 18:30:00                         |
| 07:00:00 | 16:30:00                         |
| 11:00:00 | 12:30:00                         |
| 13:00:00 | 10:30:00                         |
| 15:00:00 | 08:30:00                         |
| 17:00:00 | 06:30:00                         |
| 19:00:00 | 04:30:00                         |
| 21:00:00 | 02:30:00                         |
| 23:00:00 | 00:30:00                         |
+----------+----------------------------------+

我们发现超过20小时的价值应该是可以接受的。

  OR TIMEDIFF( CURTIME() ,  `arrivalTime` ) > MAKETIME(20,0,0)

随着需求变化为30m到4h的时差,可能需要完全改变方法以将整个时间戳转换为午夜后的秒数,然后比较差异,以一天中的秒数为模,并检查结果那个。

答案 1 :(得分:0)

是的!我终于想通了!

因为我需要一个查询来区分当天和午夜后的第二天(基于时间)到达的航班,我不得不通过更改arrivalTime列数据来稍微重新构建表(flightSched)从TIME到DATETIME。随后,现在这意味着此列中的内容以以下格式保存:YYYY-MM-DD HH:MM:SS或(2013-11-22 12:30:00)而不仅仅是12:30:00,其中更丰富。

然后我注意到下面的查询会在午夜后正确计算到下一天/日期的时间。

如果当前时间是21:00

//################################################
//## Subtract the 30 minutes from the current time
mysql> SELECT SUBTIME(NOW(), '00:30:00' );
+-------------------------------------+
| SUBTIME(NOW(),  '00:30:00' )        |
+-------------------------------------+
| 2013-11-22 20:30:00                 |
+-------------------------------------+
1 row in set (0.00 sec)

//################################################
//## Add the 4 hours to the current time


mysql> SELECT ADDTIME(NOW(),  '04:00:00');
+-------------------------------------+
| ADDTIME(NOW() ,  '04:00:00' )       |
+-------------------------------------+
| 2013-11-23 01:00:00                 |
+-------------------------------------+
1 row in set (0.00 sec)

请注意!从2013-11-22 21:00:00到2013-11-23 01:00:00,日期的变化也是如此完美。  : - )

使用下表

+-------------+----------------+-----------------+---------------------+
| FlightNo    | don            | depOrArriv      | arrivalTime         | 
+-------------+----------------+-----------------+---------------------+
| ET821       | Daily          | Arrival         | 2013-11-22 19:45:24 |
| MS838       | Tuesday        | Arrival         | 2013-11-23 01:05:24 |
| H7361       | Tuesday        | Arrival         | 2013-11-22 23:15:06 |
+-------------+----------------+-----------------+---------------------+

运行查询:

SELECT * FROM flightSched WHERE arrivalTime
                                 BETWEEN  SUBTIME(NOW(), '00:30:00')
                 AND ADDTIME(NOW(),'04:00:00')
                 ORDER BY arrivalTime ASC 

收益率:

+-------------+----------------+-----------------+---------------------+
| MS838       | Tuesday        | Arrival         | 2013-11-23 01:05:24 |
| H7361       | Tuesday        | Arrival         | 2013-11-22 23:15:06 |
+-------------+----------------+-----------------+---------------------+

非常感谢你的时间和努力。