三个日期之间的SQL查询

时间:2018-09-21 18:39:47

标签: sql sql-server date sql-server-2008 datetime

我只是想看看是否有更好的方法来执行这样的查询,我认为where子句中的强制转换是瓶颈,但不确定解决它的最佳方法是什么。执行计划中有34%是插入到临时表中,而42%是散列匹配。

SET @StartDate = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + -12, 0)
SET @EndDate = DATEADD(MILLISECOND, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))

where cast(ITF.Date as DATE) BETWEEN CAST(@StartDate as date) 
      AND CAST(@EndDate as date)

4 个答案:

答案 0 :(得分:1)

检查DATETIME值是否在两个DATE之间的最合适方法是使用date1 <= datetime AND datetime < date2,其中date2比要包含的最后日期多一天。

这不需要在datetime列上进行任何强制转换,并且可以处理datetime列包含时间值(例如23:59:59.999999)的特殊情况,并避免特定的技巧(例如减去3毫秒hack)

WHERE ITF.Date >= CAST(@StartDate as date) AND ITF.Date < CAST(@EndDate as date)

答案 1 :(得分:0)

您发布的部分代码很好,而不是引起任何性能问题的原因。

如果在执行计划中获得哈希匹配,则意味着您可能缺少两个表连接的列上的一个或多个索引。

答案 2 :(得分:0)

根据您查询的其余部分,根据我从SQL 6.5起的经验,消除@StartDate和@EndDate强制转换会加快查询速度。

DECLARE @StartDate Date DECLARE @EndDate Date

答案 3 :(得分:0)

您似乎想要:

where ITF.Date >= CAST(@StartDate as date) and
      ITF.Date < dateadd(day, 1, CAST(@EndDate as date))

Aaron Bertrand's blog“魔鬼之间的共同点”很好地解释了为什么不应该将between与日期/时间值一起使用。

请注意在结束日期前加上“ 1”。您的代码以及该版本均包含结束日期。