167

次のようなクエリがあります。

SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'

しかし、これは 1 日にデータがあっても結果が得られません。

created_atのように見え2013-05-01 22:25:19ますが、時間と関係があるのではないでしょうか? これはどのように解決できますか?

より大きな日付範囲を指定しても問題なく動作しますが、単一の日付でも (包括的に) 動作するはずです。

4

9 に答える 9

349

それ包括的です。日時と日付を比較しています。2 番目の日付は、1 日が始まる午前 0 時と解釈されます。

これを修正する 1 つの方法は次のとおりです。

SELECT *
FROM Cases
WHERE cast(created_at as date) BETWEEN '2013-05-01' AND '2013-05-01'

それを修正する別の方法は、明示的なバイナリ比較を使用することです

SELECT *
FROM Cases
WHERE created_at >= '2013-05-01' AND created_at < '2013-05-02'

Aaron Bertrand は、日付に関する長いブログ エントリ (ここ) を持っており、この問題やその他の日付の問題について説明しています。

于 2013-05-02T21:03:37.473 に答える
67

構文の 2 番目の日付参照BETWEENは魔法のように「1 日の終わり」と見なされると想定されていますが、これは正しくありません。

つまり、これは予想されていました:

SELECT * FROM ケース
WHERE created_at BETWEEN '2013-05-01'の開始と'2013-05-01 'の終了

しかし、実際に何が起こるかは次のとおりです。

SELECT * FROM ケース
WHERE created_at BETWEEN '2013-05-01 00:00:00+00000 ' AND '2013-05-01 00:00:00+00000 '

これは次と同等になります。

SELECT * FROM ケース WHERE created_at = '2013-05-01 00:00:00+00000 '

BETWEEN問題は、どちらが範囲内の下限値と上限値の両方を含むかについての認識/期待の 1 つですが、魔法のように日付を「開始」または「終了」にするわけではありません。

BETWEEN日付範囲でフィルタリングする場合は避ける必要があります。

常に>= AND <代わりに

SELECT * FROM ケース
WHERE ( created_at >= '20130501' AND created_at < '20130502')

ここでは括弧は省略可能ですが、より複雑なクエリでは重要になる場合があります。

于 2014-10-04T07:50:15.460 に答える
19

次の 2 つのオプションのいずれかを実行する必要があります。

  1. 条件に時間コンポーネントを含めますbetween: ... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59'(推奨されません...最後の段落を参照してください)
  2. の代わりに不等式を使用しbetweenます。次に、2 番目の値に 1 日追加する必要があることに注意してください。... where (created_at >= '2013-05-01' and created_at < '2013-05-02')

私の個人的な好みは 2 番目のオプションです。また、Aaron Bertrandは、なぜそれを使用すべきかについて非常に明確な説明をしています。

于 2013-05-02T21:05:54.320 に答える
9

タイムスタンプを日付として使用するだけです:

SELECT * FROM Cases WHERE date(created_at)='2013-05-01' 
于 2015-09-12T19:13:21.310 に答える
7

日時フィールドを日付フィールドと比較するための最良の解決策は次のとおりです。

DECLARE @StartDate DATE = '5/1/2013', 
        @EndDate   DATE = '5/1/2013' 

SELECT * 
FROM   cases 
WHERE  Datediff(day, created_at, @StartDate) <= 0 
       AND Datediff(day, created_at, @EndDate) >= 0 

これは、開始日と終了日、およびその間の日付の両方を含むため、包括的 between ステートメントと同じです。

于 2015-09-24T15:54:42.150 に答える
3
cast(created_at as date)

これは、2008年以降のバージョンのSQL Serverでのみ機能します

古いバージョンを使用している場合は、

convert(varchar, created_at, 101)
于 2014-05-22T19:19:48.283 に答える