SQL:BETWEEN vs <=および> =


111

SQL Server 2000および2005の場合:

  • これら2つのWHERE句の違いは何ですか?
  • どのシナリオでどのシナリオを使用すればよいですか?

クエリ1:

SELECT EventId, EventName
FROM EventMaster
WHERE EventDate BETWEEN '10/15/2009' AND '10/18/2009'

クエリ2:

SELECT EventId, EventName
FROM EventMaster
WHERE EventDate >='10/15/2009'
  AND EventDate <='10/18/2009'

(編集:2番目のイベント日付は元々欠落していたため、クエリは構文的に間違っていました)



6
実はそうではありませんが、datetimeの処理は少し異なります。さらに、SQLサーバー2008の場合も同様です。以前のバージョンでも同じ答えになることを確認せずにShyjuを特定することはできません。
Irfy、2009年

回答:


119

それらは同じです:BETWEENは、質問のより長い構文の省略形です。

BETWEEN機能しない代替の長い構文を使用してください。

Select EventId,EventName from EventMaster
where EventDate >= '10/15/2009' and EventDate < '10/18/2009'

(2番目の状態<ではなく注意してください<=。)


19
2番目の条件が「<」であることを強調する必要があるかもしれません。違いを見つけるのに少し時間がかかりました。
zendar

21
DATEデータ型を扱う場合、または日付時刻値に時刻コンポーネントが含まれないことが保証されている場合を除き、BETWEENを使用しないことを強くお勧めします。これについて一貫性があると、> =および<の代わりに誤ってBETWEENを使用する可能性が低くなり、クエリで意図していないデータを取得するか、1日余分に取得すると考えますあなたがいないときのデータ...
Aaron Bertrand

1
BETWEENが条件に変換されるとき、2番目のコンパイラー・ステップはありますか?これは少し面倒なことですが、追加のオーバーヘッドはありますか?
James Scott

1
@xmashallaxというのは彼らがそうだから?彼らはどうですか?
トニーアンドリュース

2
奇妙なことに、私は質問、回答の書き込み、コメント、および私のコードに明らかにバグがあるという事実に混乱したと思います=)
xmashallax

37

彼らは同じです。

注意すべきことの1つは、これをDATETIMEに対して使用している場合、終了日の一致はその日の始まりになります。

<= 20/10/2009

次と同じではありません:

<= 20/10/2009 23:59:59

(それは考え照合します<= 20/10/2009 00:00:00.000


その場合、「2009-10-20」と「2009-10-21」の間を使用してその日をキャプチャすることができます
David Andrei Ned

4
@DavidAndreiNedは「2009-10-21 00:00:00.000」にも一致します-おそらくあなたが望むものではありません。
Hans Ke st ing

2
フィールドBETWEEN '2009-10-20 00:00:00' AND '2009-10-20 23:59:59'またはフィールド> = '2009-10-20 00:00:00' ANDフィールド<= 「2009-10-20 23:59:59」は絶対に確実です。
geilt

@geiltあなたの例は、その日の最後の1秒間に発生したものを見落とすことになります...つまり、次の日の23:59:59と00:00:00の間です。
セス・フラワーズ

00:00:00が翌日の開始であり、>または<=を使用し、>または<を使用しない理由ですが、マイクロ秒を意味し、それらを保存する場合は、最後のマイクロ秒と最後のマイクロ秒も入力する必要があります。
geilt

14

BETWEEN読んで、保守が容易であることが閉区間で、前述のように、これは日付に問題がある可能性があるため、私はめったにその使用をお勧めしません-でも時間コンポーネントなし。

毎月のデータを扱う際に例えば、多くの場合、日付を比較するのが一般的であるBETWEEN first AND lastが、実際には、これは通常の書き込みが容易であるdt >= first AND dt < next-first(また、時刻部分の問題を解決している) -を決定するため、last通常は一歩長く決定するよりもnext-first(日差し引くことによって) 。

さらに、もう1つの問題は、下限と上限を正しい順序(つまりBETWEEN low AND high)で指定する必要があることです。


4

通常、違いBETWEENはありません。キーワードはすべてのRDBMSプラットフォームでサポートされているわけではありませんが、サポートされている場合、2つのクエリは同一である必要があります。

それらは同一であるため、速度やその他の点で違いはありません。より自然なものを使用してください。


4

@ marc_s、@ Cloudなどで言及されています。それらは基本的にクローズドレンジと同じです。

ただし、小数の時間値を使用すると、終了値が後に続く半開範囲(より大きいか等しい、より小さい)ではなく、閉じた範囲(大きいか等しい、より小さいか等しい)で問題が発生する可能性があります。最後の可能な瞬間。

したがって、クエリを次のように書き直す必要があります。

SELECT EventId, EventName
  FROM EventMaster
 WHERE (EventDate >= '2009-10-15' AND
        EventDate <  '2009-10-19')    /* <<<== 19th, not 18th */

以来はBETWEENハーフオープンの間隔のための作業は、私はいつもそのおそらくエラー以来、それを使用して任意の日付/時刻のクエリで、ハードを見ていません。


4

1つのフィールドで範囲をチェックBETWEENていること読者にすぐに理解できるので、私は少し好みがあります。これは、テーブルに同様のフィールド名がある場合に特に当てはまります。

、言うならば、私たちのテーブルには、Aの両方持っているtransactiondatetransitiondate私は読んでいる場合、

transactiondate between ...

テストの両端がこの1つのフィールドに反対していることはすぐにわかります。

私が読んだ場合

transactiondate>='2009-04-17' and transactiondate<='2009-04-22'

2つのフィールドが同じであることを確認するには、もう少し時間が必要です。

また、クエリが時間とともに編集されると、ずさんなプログラマーが2つのフィールドを分離する可能性があります。私は次のようなことを言うクエリをたくさん見ました

where transactiondate>='2009-04-17'
  and salestype='A'
  and customernumber=customer.idnumber
  and transactiondate<='2009-04-22'

BETWEENもちろん、これをで試した場合、構文エラーとなり、すぐに修正されます。


3

唯一の違いは、各クエリの構文糖の量です。BETWEENは、2番目のクエリとまったく同じように巧妙に言う方法です。

知らないRDBMS固有の違いがあるかもしれませんが、私はそうは思いません。


2

論理的にはまったく違いはありません。パフォーマンスに関しては、通常、ほとんどのDBMSで違いはありません。



1

免責事項:以下はすべて逸話的であり、私の個人的な経験から直接引用されています。より経験的に厳密な分析を行うことを考えている人は誰でもそれを実行し、私がそうであれば反対投票することができます。SQLが宣言型言語であることも知っています。コードを記述するときにコードがどのように処理されるかを考慮する必要はありませんが、時間を重視しているので、そうしています。

論理的に等価なステートメントは無限にありますが、3つと思います。

ケース1:標準順序での2つの比較(評価順序は固定)

A> = MinBoundおよびA <= MaxBound

ケース2:構文糖(評価順序は著者が選択していません)

MinBoundとMaxBoundの間

ケース3:教育された順序での2つの比較(書き込み時に選択された評価順序)

A> = MinBoundおよびA <= MaxBound

または

A <= MaxBound AND A> = MinBound

私の経験では、ケース1とケース2はデータセットを知らないため、パフォーマンスに一貫したまたは顕著な違いはありません。

ただし、ケース3は実行時間を大幅に改善できます。あなたが大規模なデータセットで作業して起こるしている場合かどうかについて、具体的には、いくつかのヒューリスティックな知識を持っているAがより大きいことが多いですMaxBoundよりか小さいMinBoundあなたが比較をケース3を使用して注文して著しく実行時間を向上させることができますそれに応じて。

私が使用している1つのユースケースは、特定の間隔内のレコードについて、インデックス付けされていない日付を持つ大規模な履歴データセットをクエリすることです。クエリを作成するとき、指定した間隔の前または指定した間隔の後にさらにデータが存在するかどうかを確認し、それに応じて比較を並べ替えることができます。データセットのサイズ、クエリの複雑さ、および最初の比較でフィルタリングされたレコードの量に応じて、実行時間が半分に短縮されました。


えっと、何?ケース3は、ケース1とケース2と同じロジックを共有しません。Aが両方の境界より大きいかどうかを確認する場合は、Aがより大きいかどうかを確認してくださいMaxBound。投稿には調整が必要です。
mickmackusa

等価演算子のタイプミスをしたようです。良いキャッチ。
LanchPad

0

このシナリオcol BETWEEN ... AND ...col <= ... and col >= ...は同等です。


SQL標準では、T461対称BETWEEN述語も定義されています。

 <between predicate part 2> ::=
 [ NOT ] BETWEEN [ ASYMMETRIC | SYMMETRIC ]
 <row value predicand> AND <row value predicand>

Transact-SQLはこの機能をサポートしていません。

BETWEEN値をソートする必要があります。例えば:

SELECT 1 WHERE 3 BETWEEN 10 AND 1
-- no rows

<=>

SELECT 1 WHERE 3 >= 10 AND 3 <= 1
-- no rows

一方:

SELECT 1 WHERE 3 BETWEEN SYMMETRIC 1 AND 10;
-- 1

SELECT 1 WHERE 3 BETWEEN SYMMETRIC 10 AND 1
-- 1

正常に機能しますBETWEENが、比較値をソートした後です。

db <> fiddleデモ

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