5

最近BETWEEN、SQLでのメソッドの使用はやや信頼性が低いとの通知を受けたため、を使用する必要がありますDATEDIFF()。ただし、別のプログラマーから、これは当てはまらないとの連絡がありBETWEEN、日付が正しくフォーマットされている限り、このメソッドはすべての場合に見事に機能します。

誰かがどちらの方法がより良いか、そしてその理由を述べることによってこの議論を解決することができますか?

現時点では、私の日付範囲SQLは次のようになっています。

DATEDIFF(d,'01-Jan-1970',SIH.[Something_Date]) >= 0 AND DATEDIFF(d,'01-Jan-2013',SIH.[Something_Date]) <= 0

ただし、信頼できると確信できる場合は、このように記述したいと思います。

SIH.[Something_Date] BETWEEN '01-Jan-1970' AND '01-Jan-2013'

この特定のケースでは、MsSQLを使用していますが、これがここでも当てはまるかどうかを知りたいので、MySQLにタグを付けました。

4

2 に答える 2

6

2つのクエリは同等ではありません。バージョンには、時間に関係なくからのdatediffすべての値が含まれますが、betweenバージョンには、時間がで01-Jan-2013ある行のみが含まれます。01-Jan-201300:00:00

範囲を確認し、列に対して計算を行わない場合、クエリはインデックスを使用できると同時に、時間部分に関係なくSomething_Dateからのすべての値を含めることができます。01-Jan-2013

where
  SIH.[Something_Date] >= '19700101' and
  SIH.[Something_Date] < '20130102'
于 2013-01-04T08:59:26.723 に答える
0

BETWEENを回避する理由は、日付値に時間コンポーネントを含めることができる場合、それを正しく使用する方法がないためです。時間が含まれている場合、上限との比較では、BETWEENを除外する比較よりも厳密に少ない値を使用する必要があります。

一方、日付の値に時間の要素が含まれないことがわかっている場合、または時間の要素を削除する便利な方法がある場合は、読みやすいように見えるため、BETWEENを使用することをお勧めします。

Oracle SQLでは、TRUNC関数を使用して時間コンポーネントを削除できます(「MONTH」または「YEAR」に切り捨てることもできます)。

だから私は書くことができます:

where TRUNC(date_col) between '01-JAN-2021' and '31-DEC-2021'

また、時間の要素もある31日の日付をテストで見逃さないようにしてください。

私は、このTRUNC(およびROUND)の使用はOracleに固有である可能性があるという印象を受けています。mySQLまたはT-SQLに同等のものがあるかどうかはわかりません。datediff( TRUNCが行うことを達成するためにトリックを使用しなければならなかったことを覚えているようです。

なしTRUNC(または同等のもの)では、以下を使用する必要があります。

where '01-JAN-2021' <= date_col and date_col < '01-JAN-2022'

上限との比較は厳密に未満でなければならないことに注意してください。

これはより短く、非常に読みやすく、おそらくより効率的で、動作が保証されています。

TRUNCしかし、私はまだ使用することを好みBETWEEN、ロジックがよりクリーンであるためです。(私はそれを正しくする前に2つの異なる方法で2番目の例を台無しにしました)。

効率に大きな違いがあるのではないかと思います。ほとんどの場合、問題はないでしょう。効率よりも読み取り可能性の方が重要だと思います(ほとんどの場合)。

しかしもちろん、正しさはすべてに勝ります。したがって、時間コンポーネントを削除する便利な方法がない場合、または時間コンポーネントを含める必要がある場合は、値BETWEENを正確にテストするために使用することはできませんdatetime

于 2022-01-28T05:31:30.783 に答える