web-dev-qa-db-ja.com

SQL:BETWEEN vs <=および> =

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番目のイベント日付はもともと欠落していたため、クエリは構文的に間違っていました)

97
Shyju

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

BETWEENが機能しない代替のより長い構文を使用します。

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

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

102
Tony Andrews

それらは同じです。

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

<= 20/10/2009

以下と同じではありません:

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

(それはwould<= 20/10/2009 00:00:00.000と一致)

33
Irfy

BETWEENは読みやすく、保守も簡単ですが、閉じた間隔であり、前述のとおり、これは日付の問題である可能性があるため、時間コンポーネントがなくても使用することはめったにありません。

たとえば、月ごとのデータを扱う場合、日付を比較するのが一般的ですBETWEEN first AND lastが、実際にはdt >= first AND dt < next-first(これは時間部分の問題も解決します)を書く方が簡単です-lastは、通常next-first(1日減算)を決定するよりも1ステップ長くなります。

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

13
Cade Roux

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

それらは同一であるため、速度などの点で実際に区別はありません。より自然なものを使用してください。

4
marc_s

@ marc_s、@ Cloudなどが言及しているように閉じた範囲でも基本的に同じです。

ただし、時間の小数値は、半開範囲(以上)とは対照的に、閉範囲(以上または未満)で問題を引き起こす可能性があります等しいおよびless-than)で、終了値afterの最後の可能な瞬間。

そのため、クエリを次のように書き換える必要があります。

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

BETWEENは半開間隔では機能しないので、おそらくエラーであるため、それを使用する日付/時刻クエリを常に注意深く調べます。

4
devstuff

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

たとえば、テーブルに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
Jay

唯一の違いは、各クエリの構文糖の量だと思います。 BETWEENは、2番目のクエリとまったく同じように表現するための洗練された方法です。

RDBMS固有の違いは気付いていないかもしれませんが、そうは思いません。

3
pyrocumulus

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

2
mjv

これを参照してください 優秀なブログ投稿 from Aaron Bertrand 文字列形式を変更する理由と、日付範囲クエリでの境界値の処理方法について。

2
Andy Jones

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

論理的に等価な無限のステートメントがありますが、3つ(ish)を検討します。

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

A> = MinBound AND A <= MaxBound

ケース2:構文糖衣(評価順序は著者によって選択されていない)

MinBoundとMaxBoundの間

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

A> = MinBound AND A <= MaxBound

または

A <= MaxBound AND A> = MinBound

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

ただし、ケース3は実行時間を大幅に改善できます。具体的には、大きなデータセットを使用していて、AMaxBoundよりも大きい可能性が高いかどうかについて、何らかの発見的知識がある場合MinBoundケース3を使用し、それに応じて比較を順序付けることにより、実行時間を大幅に改善できます。

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

0
LanchPad