0

以下に示すように、フライト番号、フライトの到着日、到着または出発の有無、そして最も重要な到着時刻を含むテーブル (flightSched) があります。

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

現在時刻から現在時刻の 4 時間前までのすべてのフライトをテーブルに表示したいと考えています。

私のクエリの下を見つけます

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

フライトが真夜中を過ぎて到着/出発するまで、クエリは完全に機能します。上記の表より、現在時刻が21:00:00の場合、便名MS838は表示されません。どこが間違っていますか?

クエリのどこが間違っているのか、誰か親切に指摘できますか?

4

2 に答える 2

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句を useに変更し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                       |
+----------+---------------------------------+

将来の時間は負の時差になります (示されている順序で引数が提供されます)。許容可能 (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)

要件が 30 分から 4 時間の時差に変更されたため、アプローチを完全に変更して、タイムスタンプ全体を午前 0 時を過ぎた秒数に変換し、その差を 1 日の秒数でモジュロして比較し、その結果を確認する価値があります。

于 2013-11-06T17:48:26.497 に答える