質問

日付Aから日付Bまでのレコードを返すようにレポートを制限したい。これは私がやっていることです。

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date between @startDate and @endDate

... 1月1日の午前12時から3月31日の午後11時59分までのレコードを返しました(時刻が指定されていない場合の真夜中がデフォルトです)。しかし、矛盾があることに気付きました。つまり、レコードの時刻が00:00:00である場合、このセットの一部になります。

これを行うより正確な方法はありますので、私が望む日付範囲を正確に返しますか?

時間を使用してみました:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008 00:00:00'
set @endDate = '04/01/2008 11:59:59'
-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date between @startDate and @endDate

...しかし、私は何か奇妙なことに気付きました。SQLServerは100分の1秒を半周します。 11:59:29以降に使用すると、4月1日のレコード(ha!エイプリルフールのレコード!grr)が得られます。なぜですか?

  • (確かにあります。これは初めてです。ご協力ありがとうございます!)
役に立ちましたか?

解決

常に簡単なオプションがあります:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'

-- test what are the start and end dates
select min(date),max(date) from view_Inspections 
where date >= @startDate 
and   date < @endDate

他のヒント

view_Inspectionsの日付列はSmallDateTimeデータ型であると思われます。このデータ型の精度は1分であり、予期しない結果を説明します(秒を最も近い分に丸める)。

Roland Shawが提案する方法は、要件に合わせてクエリを変更する最適な方法です。

BETWEEN演算子は包括的であるため、最初のクエリで結果が表示されます。 2番目のクエリで表示される丸めは、テーブルで使用している正確な日時データ型に依存します。 (ところで、あなたは秒を100分の1秒と混同していると思います)。テーブルでsmalldatetimeを使用しているようです。その場合、時間は最も近い分に丸められます。

テーブルが日時を使用している場合は、@ startDateおよび@endDateを明示的にDATETIME値に変換してみてください(CAST(@endDate AS DATETIME))。

簡単な注意... DATETIME値の場合でも、SQL Serverは3/100秒までしか正確ではないため、11:59:59.999は12:00:00.000に切り上げられます。

基本的に3つの選択肢があります:

1)CAST('01 / 01/2008 00:00:00.000 'as DATETIME)とCAST('03 / 31/2008 12:59:59.997' AS DATETIME)

2)YEAR(my_date)= 2008 AND MONTH(my_date)BETWEEN 1 AND 3

3)my_date <!> gt; = CAST('01 / 01/2008 00:00:00.000 'AS DATETIME)AND my_date <!> lt; CAST('04 / 01/2008 00:00:00.000 'AS DATETIME)

最初の方法はあまり直感的ではなく、私の意見ではエラーを起こしやすいです。 2番目の方法では、インデックスを使用できないためパフォーマンスが低下します。また、数年にわたる検索や月の途中で開始/終了する検索を行うことができる場合、より複雑になります。 Rowlandが提案した3番目の方法は、私が考える最高の方法です。

次のように、日付フィールドから時間を削除するだけです:

declare @startDate varchar(20)
declare @endDate varchar(20)
set @startDate = '01/01/2008'
set @endDate = '04/01/2008'

SELECT min(date),max(date) FROM view_Inspections 
WHERE CAST(FLOOR(CAST(date AS FLOAT)) AS DATETIME) BETWEEN CAST(@startDate AS DATETIME) And CAST(@startDate AS DATETIME))

これは、01/01/2008 00:00:00から04/01/2008 11:59:59.999までのすべてを返します。 04/01を含めたくない場合は、終了日を03/31/2008に変更します。

最善の解決策は、<!> quot; julian <!> quot;と呼ばれるBIGINT(10)フィールドを作成し、YYYYMMDDに保存することです。

クエリを実行します ここで、ジュリアン<!> gt; = '20120103' ANDジュリアン<!> lt; = '20120203'

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top