web-dev-qa-db-ja.com

SQL「の間に」包括的ではありません

このようなクエリがあります:

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

ただし、1日のデータがあったとしても結果は得られません。

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

日付範囲を大きくするとうまく機能しますが、単一の日付でも(包括的に)動作するはずです。

105
JBurace

それis包括的。日付時刻を日付と比較しています。 2番目の日付は真夜中日が始まるときと解釈されます。

これを修正する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には、日付に関する長いブログエントリ( here )があり、ここでこの問題やその他の日付の問題について議論しています。

240
Gordon Linoff

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

すなわち、これは予想されていた:

 SELECT * FROMケース
 WHERE created_at BETWEEN の始まり '2013-05-01' AND の終わり 「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つです。これは、範囲内の下限値と上限値の両方をdoes含みますが、does魔法のように日付を「開始」にします「または「の終わり」。

日付範囲でフィルタリングする場合は、BETWEENは使用しないでください。

常に代わりに>= AND <を使用します

 SELECT * FROMケース
 WHERE(created_at > = 「20130501」 そして created_at < '20130502')

括弧はここではオプションですが、より複雑なクエリでは重要になる場合があります。

36
Used_By_Already

次の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 には 非常に明確な説明 使用すべき理由が記載されています。

15
Barranka

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

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 

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

5
Ted

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

SELECT * FROM Cases WHERE date(created_at)='2013-05-01' 
5
Balinti
cast(created_at as date)

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

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

convert(varchar, created_at, 101)
1
Ali Adravi

日時から日付を抽出し、結果を包括的日付として与えるdate()関数を使用できます。

SELECT * FROM Cases WHERE date(created_at)='2013-05-01' AND '2013-05-01'
0
abhishek kumar