2

SQL Server の varchar 型の列名として batch_dt を持つ book_data という名前のテーブルがあります。

クエリを渡すとき

SELECT DISTINCT batch FROM book_data 

次の結果が得られます

  batch_dt
-------------
 2012-10-31
-------------
 2012-11-01
-------------
 2012-11-02
-------------
 2012-11-03
-------------
      .
      .
      .

今私がやっていることは、2 つの日付間のレコードの総数を取得することです。かなり単純なクエリ。

SELECT COUNT(*) FROM book_data WHERE CONVERT(varchar(12),CONVERT(datetime,batch_dt),101) BETWEEN '11/02/2012' and '10/31/2012'

結果は 112

月を02から2に変更するだけで、クエリは218の結果を返します

SELECT COUNT(*) FROM book_data WHERE CONVERT(varchar(12),CONVERT(datetime,batch_dt),101) BETWEEN '11/2/2012' and '10/31/2012'

なぜこの異なる動作ですか?

4

4 に答える 4

3

代わりに を使用CAST(batch_dt AS DATE)し、言語に依存しない形式で日付を渡しますYYYYMMDD。この方法では、日付としてではなく、次のように表示されますvarchar

SELECT COUNT(*) 
FROM book_data 
WHERE CAST(batch_dt AS DATE)
BETWEEN '20121102' and '20121130'

ただし、これは安全ではありませんbarch_dt。間違った形式の値が含まれていると、キャスト エラーが発生します。この場合ISDATE(batch_dt) = 1、有効なデータ時間であることを確認するために追加できます。ただし、この列を datatype にした方がよいでしょうDateTime

注意すべきもう 1 つの点は、SQL Server では非対称で あることBETWEENです。つまり、次のように評価されます。BETWEEN '11/02/2012' and '10/31/2012'

DATE >= '11/02/2012' 
AND
DATE <= '10/31/2012'

これは決して真実ではありません。それが機能する理由は、日付が日付としてではなく文字列として比較されたためです。しかし、あなたはそれを維持しなければなりませんBETWEEN the small value and the biggest value

于 2013-01-22T07:43:34.123 に答える
2

string を と比較しますBETWEEN。そうする場合は、正しい順序で比較することを確認する必要があります => YYYYMMDD MM:SS が正しい順序になります。

可能な場合は、タイプを指定して列を追加datetimeし、データベースに実際の日時の値を保存してください。それができない場合は、値を分割して自分で日付値を作成できます。CONVERT()これは単にorを使用するよりもはるかに遅くなりCAST()ますが、間違った日付文字列でも機能することを確認できます。

キーワードを使用PATINDEX(),LEFT(),RIGHT()して必要な値を取得するか、split() 関数を使用できます (多くのバージョンの Google を見つけることができます。例: https://codereview.stackexchange.com/questions/15125/sql-server-split-function-最適化)。分割機能を使用する場合は、分割/して位置から年、月、日を取得します。

ただし、正しい日時の値をデータベースに保存することをお勧めします。

于 2013-01-22T07:53:22.810 に答える
1
SELECT COUNT(*) 
FROM book_data 
WHERE CONVERT(DATETIME,batch_dt,101) BETWEEN '11/2/2012' and '10/31/2012'

この方が適切でしょう

于 2013-01-22T07:41:57.697 に答える
1

日付ではなく文字列/varcharを比較するため、この異なる動作が得られます。

Date(またはDateTime) の場合、は10/2/2012と同じ10/02/2012です。

しかしstring、これらの値は(もちろん)異なっています。それはまるであなたが比較するかのよう'abcd'です'ab0cd'

于 2013-01-22T07:55:06.167 に答える