SQL:BETWEEN vs< = and> =
-
06-07-2019 - |
質問
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番目のイベント日付が元々欠落していたため、クエリが構文的に間違っていました)
解決
これらは同じです。 BETWEEN
は、質問の長い構文の省略形です。
BETWEEN
が機能しない代替の長い構文を使用します。例:
Select EventId,EventName from EventMaster
where EventDate >= '10/15/2009' and EventDate < '10/18/2009'
(2番目の条件では&lt; =
ではなく&lt;
に注意してください。)
他のヒント
これらは同じです。
注意すべきことの1つは、DATETIMEに対してこれを使用している場合、終了日の一致はその日の始まりになります:
<= 20/10/2009
は次とは異なります:
<= 20/10/2009 23:59:59
(&lt; = 20/10/2009 00:00:00.000
と一致する )
BETWEEN
は読みやすく保守も簡単ですが、閉じた間隔であり、前述のように、これは日付の問題である可能性があるため、時間コンポーネントがなくても使用することはめったにありません。
たとえば、月次データを扱う場合、日付を BETWEEN first AND last
で比較することがよくありますが、実際には、これは通常 dt&gt; = first AND dt&lt ; next-first
(時間部分の問題も解決します)- last
を決定することは、通常 next-first
を決定するよりも1ステップ長いため。
さらに、もう1つの落とし穴は、下限と上限を正しい順序(つまり、 BETWEEN low AND high
)で指定する必要があることです。
通常、違いはありません- BETWEEN
キーワードはすべてのRDBMSプラットフォームでサポートされているわけではありませんが、サポートされている場合、2つのクエリは同一である必要があります。
これらは同一であるため、速度などの点で実際に区別はありません。より自然なものを使用してください。
@ marc_s、@ Cloudなどが言及しているように閉じた範囲でも基本的に同じです。
ただし、時間値の端数は、半開範囲(以上および以下)ではなく、閉範囲(以上および以下)で問題を引き起こす可能性があります小なり)、最後の可能な瞬間の後に終了値を設定します。
したがって、クエリが次のように書き換えられることを避けるために
SELECT EventId, EventName
FROM EventMaster
WHERE (EventDate >= '2009-10-15' AND
EventDate < '2009-10-19') /* <<<== 19th, not 18th */
BETWEEN
は半分開いた間隔では機能しないため、おそらくエラーであるため、それを使用する日付/時刻クエリを常に注意深く調べます。
唯一の違いは、各クエリの構文糖の量だと思います。 BETWEENは、2番目のクエリとまったく同じ言い方です。
RDBMS固有の違いがあるかもしれませんが、気付いていませんが、そうは思いません。
BETWEEN
を少し好みますが、これは読者に範囲の1つのフィールドをチェックしていることを即座に明らかにするからです。これは、テーブルに同様のフィールド名がある場合に特に当てはまります。
たとえば、テーブルに transactiondate
と transitiondate
の両方がある場合、私が読んだ場合
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
でこれを試すと、もちろん構文エラーになり、すぐに修正されます。
論理的にはまったく違いはありません。 パフォーマンスに関しては、通常、ほとんどのDBMSでまったく違いはありません。
こちらをご覧ください Aaron Bertrand の優れたブログ投稿で、文字列形式を変更する理由と日付範囲クエリでの境界値の処理方法。
免責事項:以下はすべて逸話に過ぎず、私の個人的な経験から直接引用したものです。より経験的に厳密な分析を行うことを考えている人は誰でも、私がそうであるなら、それを実行し、反対票を投じることを歓迎します。また、SQLは宣言型言語であり、コードの記述時にコードがどのように処理されるかを考慮する必要はないことも承知していますが、時間を大切にしているため、そうします。
論理的に等価な無限のステートメントがありますが、3つ(ish)を検討します。
ケース1:標準的な順序での2つの比較(評価順序は固定)
A&gt; = MinBound AND A&lt; = MaxBound
ケース2:構文糖(評価順序は作成者によって選択されません)
MinBoundとMaxBoundの間
ケース3:教育的な順序での2つの比較(書き込み時に選択された評価順序)
A&gt; = MinBound AND A&gt; = MaxBound
または
A&gt; = MaxBound AND A&gt; = MinBound
私の経験では、ケース1とケース2はデータセットを無視するため、一貫性のある、または顕著なパフォーマンスの違いはありません。
ただし、ケース3では実行時間を大幅に改善できます。具体的には、大規模なデータセットを使用しており、 A が MaxBound よりも大きいか、または< strong> MinBound の場合、ケース3を使用し、それに応じて比較を順序付けることにより、実行時間を大幅に改善できます。
1つのユースケースは、特定の間隔内のレコードのインデックス付けされていない日付を持つ大きな履歴データセットをクエリすることです。クエリを作成するとき、指定された間隔の前または指定された間隔の後にさらにデータが存在するかどうかがわかり、それに応じて比較を順序付けることができます。データセットのサイズ、クエリの複雑さ、最初の比較でフィルタリングされたレコードの量に応じて、実行時間が半分に短縮されました。