MySQLの「between」節は含まれていませんか?


142

between句を使用してクエリを実行すると、終了値が除外されているようです。
例えば:

select * from person where dob between '2011-01-01' and '2011-01-31'

これによりdob、「2011-01-01」から「2011-01-30」までのすべての結果が取得されます。dob「2011-01-31」のレコードをスキップします。このクエリがこのように動作する理由、およびdob「2011-01-31」がどこにあるレコードを含めるように変更することができるかを誰かが説明できますか?(ユーザーが選択したため、終了日に1を追加しません。)


いいえ。私のMySQLインストール(バージョン?)にBETWEENは、両方の値が含まれています。私はMySQL Server 5.7Windows 10 を使用しています
Green

回答:


181

フィールドにはdobおそらく時間コンポーネントがあります。

それを切り捨てるには:

select * from person 
where CAST(dob AS DATE) between '2011-01-01' and '2011-01-31'

59
代わりにCAST(dob AS DATE)、より簡潔なものを使用できますDATE(dob)
jkndrkn 2011

11
これは機能しますが>=、の<代わりにおよびを使用すると、パフォーマンスが向上しますbetween
David Harkness 2012年

112
を使用すると、パフォーマンスが向上しdob BETWEEN '2011-01-01 00:00:00' AND '2011-01-31 23:59:59ます。これは、DATE(dob)が各行の値を計算する必要があり、そのフィールドでインデックスを使用できないためです。
joshuahedlund 2012

2
@joshuahedlundこのソリューションで回答を追加してください。CASTはそれほど効率的ではありません。
doc_id 2015年

3
@joshuahedlundこれは、時間のあるデータが得られるまで機能しますt > 23:59:59 and t < 24:00:00。どうして指定が不十分なのBETWEENか。むしろ、Davidのアドバイスに従って使用してくださいWHERE dob >= '2011-01-01' AND dob < '2011-02-01'。最高のパフォーマンス、そしてそれは毎回機能します。
幻滅'27

300

以下からのMySQL-マニュアル

これは式(min <= expr AND expr <= max)と同等です。


3
この回答にリンクされているマニュアルは、DATEオブジェクトとDATETIMEオブジェクトを比較する場合はキャストが推奨されることを示しています。だから私は@tiagoinuが厳密な意味で最も完全な答えを持っていると思いますが、どちらも正しいです。
Kingsolmn 2013年

@jemmingerは答えがでているためかもしれライバル P:男-postgres
nawfal

27
要するに、包括的です...それがこの答えが揺るがす理由です。
ラファエル

6
古いコメントですが、これを特定のクエリに関連付けたいと思いました。「BETWEEN」は包括的ですが、時刻が指定されていない日付は00:00:00まで埋め込みます。したがって、日付範囲で比較すると、最終日が失われます。DATE(dob)を呼び出すか、一日の終わりを指定してください。
wintermute92 2016

彼らは練習は金であると言います、私のユースケースからそれは全く包括的ではありません、なぜこれが私で起こるのかと思います。私は試しましたが、うまくいかないこともあります。TIMEデータフィールドで使用します。
Jeffery ThaGintoki

99

問題は、2011-01-31が実際には2011-01-31 00:00:00であることです。それが一日の始まりです。日中のすべてが含まれていません。


19
これは本当に何が起こっているのかを説明し、質問に答えます。
Ivan P

3
それらすべての年の後で、この答えはまだ最高です。どうもありがとう。
Strabek 2017

31
select * from person where dob between '2011-01-01 00:00:00' and '2011-01-31 23:59:59'

1
私は考えて、それはそれを注目に値する、これは時の日付は含まれません2011-01-31 23:59:59が、それらにまで含まれています2011-01-31 23:59:58 含まれていないその日の最後の秒をそれはマイナーかもしれない誰かの恩恵を受ける。
doc_id 2015年

1
MySQLドキュメントのrahmanisback BETWEENは双方向に含まれるため、最後の1秒が含まれることを確認できます。dev.mysql.com/doc/refman/5.5/en/…を
Felype

1
はい、@ Felypeのとおりです。私はこれをmysqlデータベースで自分で確認しました。23:59:59結果にも含まれます。したがって、その両方の方法が含まれます。
ラッキー

2
dob列が1秒未満の精度のタイムスタンプである場合、BETWEEN代わりに「2011-02-01 00:00:00」を使用しない限り、その日の最後の秒内のイベントを見逃すことはありませんか?
窒素

1
-1。含まれません2011-01-31 23:59:59.003。使用@nitrogenが2011-02-01 000:00:00します誤っ理由は2月1日....上のゼロ時間を含める>=と、<代わりに使用する必要があります。
幻滅

6

クエリで参照しているフィールドは、Date型またはDateTime型ですか?

説明する動作の一般的な原因は、DateTime型を使用する場合で、実際にはDate型を使用する必要があります。つまり、誰かが生まれた時間を本当に知る必要がない限り、日付タイプを使用します。

最終日が結果に含まれていない理由は、クエリで指定していない日付の時間部分をクエリが想定しているためです。

つまり、クエリは2011-01-30と2011-01-31の間で真夜中まで解釈されますが、データには2011-01-31の当日の後半に値が含まれる場合があります。

提案:フィールドがDateTimeタイプの場合は、フィールドを日付タイプに変更してください。


4

こんにちは、このクエリは私にとってうまくいきます、

select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'

2
select * from person where DATE(dob) between '2011-01-01' and '2011-01-31'

驚くべきことに、このような変換はMySQLの多くの問題の解決策です。


10
驚いたことに、これは、受け入れられた回答(および他のいくつかの回答)が言ったこととまったく同じです...あなたがそうする2年前。
クリスベイカー

0

上の日付を日付+ 1日に設定するので、この場合は2011-02-01に設定してください。


1
これには、誤って 2月1日のゼロ時間が含まBETWEENれます。代わりに使用する必要が>=あり<ます。
幻滅2017

0

クエリは次のように実行できます。

select * from person where dob between '2011-01-01' and '2011-01-31 23:59:59'

他の人が指摘したように、日付がハードコーディングされている場合。

一方、日付が別のテーブルにある場合は、次のように日を追加して秒を引くことができます(日付が秒/時間なしで保存されている場合)。

select * from person JOIN some_table ... where dob between some_table.initial_date and (some_table.final_date + INTERVAL 1 DAY - INTERVAL 1 SECOND)

dob(受け入れられた回答のように)フィールドでキャストを実行しないでください。これにより、パフォーマンスの問題が大きくなる可能性があります(dobフィールドにインデックスがあると仮定すると、インデックスを使用できないなど)。またはのようなものを作成するusing index conditionusing where、実行計画がからに変わる可能性があるので注意してください。DATE(dob)CAST(dob AS DATE)


0

MySqlでは、値の間は包括的であるため、「2011-01-01」と「2011-01-31」の間を取得しようとすると

それはから2011-01-01 00:00:00まで含まれる2011-01-31 00:00:00 ため、2011-01-31では時間が経過するはずなので、実際には何もありません。2011-01-31 00:00:00 ~ 2011-01-31 23:59:59

上限については、2011-02-01次に変更することができ、それはすべてのデータを取得します2011-01-31 23:59:59

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