在 T-SQL 中比较日期,忽略时间部分

69
我正在使用MS SQL 2005,想要检查两个日期是否相等,但忽略时间部分。
我知道可以使用DATEDIFF,但担心速度会很慢——这个存储过程在数据库中被广泛使用!
有什么建议吗? 编辑: David Andres的评论:
'“比较”包括比相等更多'
让我意识到我的问题没有表述清楚——我只是检查是否相等,仅此而已。

11
不要过早优化:使用DATEDIFF编写查询,然后通过检查查询计划来确定是否存在瓶颈。如果有问题,请寻找替代方案,但不要改变原始查询的结构。 - Welbog
可能是一个重复问题,参考SQL Server中移除日期时间中的时间部分的最佳方法 - abatishchev
5个回答

102

最合理的方法是去除日期时间值的时间部分并比较结果,从datetime中去除时间部分的最佳方法如下:

cast(current_timestamp as date)    

我曾经使用并推崇如下两行代码:

cast(floor(cast(getdate() as float)) as datetime)
dateadd(dd,0, datediff(dd,0, getDate()))
但是现在 Sql Server 有了 Date 类型,不包含时间部分,因此很少有理由使用这些技术。还需要记住的一件事是,如果您需要在 where 子句或联接条件中为每行执行两个 datetime 值的操作,这仍然会拖慢查询速度。如果可能的话,最好将其因式分解,使其尽可能地预计算,例如使用视图或计算列。

最后,请注意 DATEDIFF 函数比较越过的边界数量。这意味着 '2009-09-14 11:59:59''2009-09-15 00:00:01' 之间的日期差异天数为 1,即使只过去了 2 秒,但 '2009-09-15 00:00:01''2009-09-15 11:59:59' 之间的日期差异天数仍为零,即使经过了 86,398 秒。它实际上并不关心那里的时间部分,只关心边界。根据您的查询目的,您可能能够利用它。


4
与其使用“_DATEDIFF(day, date1, date2)_”相比,那不会更加低效吗? - KM.
2
我并不是在寻找去除时间的方法,而是想要比较两个日期而忽略时间的方法。这看起来对我来说有点慢。 - Fiona - myaccessible.website
1
我所说的“其他”方法是使用计算列,在计算中使用时间剥离代码来处理您的日期时间列。这将使SQL服务器提前完成所有工作,因此您只需说“DateA - DateB”。 - Joel Coehoorn
1
一个持久化的计算列会提前完成它,而视图和计算列只会按需完成。 - KM.
1
说实话,如果没有提到将索引列引用包装在函数内的影响,这个讨论就不完整... 这会阻止条件成为SARGable。我知道你使用了GetDate(),所以并不是在提倡它,但如果提到它会更好。 - ErikE
显示剩余3条评论

42

当DATEDIFF(day, date1, date2)等于0时


7

在我的工作中,当我想要确定两个日期是否相等时,不考虑时间的影响,我使用了以下方法:

WHERE CONVERT(VARCHAR, date1, 101) = CONVERT(VARCHAR, date2, 101)

当然,“比较”不仅包括相等,上述内容将日期转换为美国格式 MM/DD/YYYY 以进行比较。因此,性能影响和无法比较日期差异。

但是...它确实有效。


4
如果你的业务需求无法通过数据模型很好地实现(例如,你需要比较日期,但只跟踪日期加时间而不是日期),可以考虑调整模型而不是应对方法。
是否可以在索引计算列中仅存储日期或将日期和时间部分分开存储?这样做是否有帮助?

3

很抱歉回复晚了。

我经常使用这种语法进行日期比较。

WHERE CONVERT(VARCHAR(8), date1, 112) = WHERE CONVERT(VARCHAR(8), date2, 112)

每当我们使用112格式代码转换日期时,它总是表现出色,返回的日期格式为yyyyMMdd。尽管它在没有时间的字符串格式下比较日期,但效果非常好。谢谢。


你的解决方案在我编写的脚本上起作用了,当“IF date_column!= GETDATE()”时没有起作用。你知道为什么吗? - CryptoJones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接