MySQLはDATE文字列をDATETIMEフィールドの文字列と比較します


89

質問があります:1つのDATE文字列「2010-04-29」をDATETIME(2010-04-29 10:00)として格納されている文字列と比較することで、MySQLデータベースから選択することはできますか?

データをフィルターする1つの日付ピッカーがあり、次のようにDATETIMEフィールドでテーブルをクエリしたいと思います。

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

...そして、DATETIME値が「2010-04-29 10:00」である行を取得したいと考えています。

助言がありますか?ありがとう。

回答:


159

以下を使用します。

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

参考までに、200万のレコードテーブルがあるので、同様のクエリを実行しました。Salilsの回答には4.48秒、上記には2.25秒かかりました。

したがって、テーブルがBIGの場合は、むしろこれをお勧めします。


8
最初の答えは非常に遅いので、比較する前に各日時を文字列にフォーマットする必要があります。フィールドの日付部分のみを直接比較しますが、それでもインデックスを使用できないため、あなたの方が優れています(mysql 5.1でテスト済み)
Marki555

1
パフォーマンスに問題がある場合は、日付と時刻の部分を個別に保存して、日付の部分にINDEXを配置できるようにすることを検討してください。
Thijs Riezebeek、2015

1
インデックスが作成されている場合、このクエリはインデックスを使用できませんstartTime
Zamrony P. Juhara

41

DATETIME列のDATE部分が特定のリテラルと一致するすべての行を選択する場合、次のようにすることはできません。

WHERE startTime = '2010-04-29'

MySQLはDATEとDATETIMEを直接比較できないためです。MySQLが行うことは、与えられたDATEリテラルを時間'00:00:00 'で拡張します。だからあなたの状態は

WHERE startTime = '2010-04-29 00:00:00'

確かにあなたが望むものではありません!

条件は範囲であるため、範囲として指定する必要があります。いくつかの可能性があります:

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

最初の日付が間違っている可能性はわずかです-DATETIME列がサブセカンドの解像度を使用していて、23:59:59 +イプシロンに予定がある場合。一般に、2番目のバリアントを使用することをお勧めします。

どちらのバリアントも、テーブルが大きくなると重要になるstartTimeのインデックスを使用できます。


9
Davidのバージョンは適切ではありません。インデックスを使用できません。インデックスを使用するには、いない機能(の結果に、直接列にフィルタを持ってdate()year()datediff()または任意の同様の)
Marki555

mysqlが日付をdatetimeに変換する方法を探していました00:00:00。今私の結果は理にかなっている
会計士م

1
これは、可能であればインデックスを使用できない他の回答と比較して正しい高速なソリューションです
Zamrony P. Juhara

23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

または

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

23
これはひどいクエリです。絶対にこれを避けてください。startTimeにインデックスがある場合は、直接使用するのではなく、列に関数を適用するため、このクエリでは使用できません。つまり、このようなクエリでは全表スキャンが必要になります。大きなテーブルでは、これは非常に遅いクエリを意味します。
steveayre 2013年

私は同意します、彼の答えは間違っています-正しい答えは以下のデイビッドによって投稿されました。
mindplay.dk 2013

1
デイビッドからの答えを使用してください。これは有効ですが、速度には良くありません...
xarlymg89

1
@CarlosAlbertoMartínezGadeaこのバージョンは、比較する前に各値を文字列にフォーマットする必要があるため、処理が遅くなります... Davidのバージョンでは必要ありませんが、インデックスを使用できないため、最適ではありません。索引を使用できるバージョンについては、XL_からの回答を参照してください。残念ながら、mysqlで適切に実行するためのより良い方法はありません
Marki555

1
クエリがインデックスを使用できないため、この回答に反対しましたが、@ XL_の回答は使用します。
pedromanoel 14年

2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

これはを使用したmysqlの日時形式の場合DATE_FORMAT(date,format)


1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

それは役立ちます、あなたがDATE比較する前のように値を変換することができます。


0

次のように、DATETIMEフィールドをDATEにキャストできます。

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

これは非常に効率的です。


1
いいえ、それも効率的ではありません。インデックスが作成されている場合、これstartTimeはインデックスを使用できません
Zamrony P. Juhara

-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

MySQLの日付で比較演算子を使用して、前後に何かを検索することもできます。これは、単純な文字列の並べ替えで正しく並べ替えられるような方法(最大値から先頭のゼロで最小値)で記述されているためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.