日付列のインデックスを使用できるように、クエリを引数可能にすることが重要です。したがって、関数(日付)(関数は年、月、または日付部分)の形式のwhere句は、SQL Serverが日付のインデックスを使用できないため、不適切です。
代わりに、クエリをフレーム化して、次の形式にする必要があります
select *
from table1
where (date is null) or (date between [STARTOFMONTH] and [ENDOFMONTH])
DateTime列には、その名前が示すように、TIMEコンポーネントがあります。したがって、月末の真夜中までにしたいので、その間は注意が必要ですが、翌月につながる真夜中ではありません...月末から3ミリ秒を引くことで、これを回避しようとする人もいます。それは悪いことであり、将来の保証ではありません。
クエリを次のように表示することをお勧めします
select *
from table1
where (date is null) or ( (date >= [STARTOFMONTH] and date < [STARTOFNEXTMONTH]) )
それらの値を取得する方法(そしてSQL 2000と互換性がある...)?頭のてっぺんから離れた1つの方法は
cast( floor( cast(dateAdd(d, -1 * day(getDate()) + 1, getDate()) as float ) ) as datetime )
翌月の開始は、それに1か月を加算することによって取得されます。これにより、現在の日付が取得され、現在の月に経過した日数が差し引かれ、1が加算されます。次に、月の最初の日に等しい日付/時刻がありますが、時間コンポーネントがあります。フロート、フロア、そして日時にキャストバックするキャストはそれを修正します。
これはスカラーまたはインラインテーブルUDFに入れることができますが、簡潔にするために(すでに長い答えです!)、where句は
select *
from table1
where
(date is null)
OR
(
( date >= cast( floor( cast(dateAdd(d, -1 * day(getDate()) + 1, getDate()) as float ) ) as datetime ) )
AND
( date < dateAdd(d, 1, cast( floor( cast(dateAdd(d, -1 * day(getDate()) + 1, getDate()) as float ) ) as datetime ) ) )
)
お役に立てば幸いです。