重要的是使您的查询可搜索,以便可以使用日期列上的索引。因此,形式为 function(date)(其中 function 是年、月或 datepart)的 where 子句是不好的,因为 SQL Server 不能使用日期索引。
相反,您希望构建您的查询,使其具有以下形式
select *
from table1
where (date is null) or (date between [STARTOFMONTH] and [ENDOFMONTH])
顾名思义,DateTime 列有一个 TIME 组件。所以 between 很棘手,因为你想要一直到月底的午夜,但不是午夜到下个月......有些人试图通过从月底减去 3 毫秒来解决这个问题。这很糟糕,而且不是未来的证据。
最好让您的查询看起来像
select *
from table1
where (date is null) or ( (date >= [STARTOFMONTH] and date < [STARTOFNEXTMONTH]) )
如何获得这些值(并与 SQL 2000 兼容......)?一种方法,在我的脑海中,是
cast( floor( cast(dateAdd(d, -1 * day(getDate()) + 1, getDate()) as float ) ) as datetime )
下个月的开始是通过增加一个月来获得的。这将获取当前日期,减去当前月份经过的天数,然后加 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 ) ) )
)
希望有帮助!