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

Posted

技术标签:

【中文标题】在 T-SQL 中比较日期,忽略时间部分【英文标题】:Compare dates in T-SQL, ignoring the time part 【发布时间】:2009-09-15 14:17:31 【问题描述】:

我使用的是 MS SQL 2005,我想检查两个日期是否相等,但忽略时间部分。

我知道我可以使用DATEDIFF,但我担心它可能会很慢 - 这个 SP 经常在数据库中使用!

有什么建议吗?

编辑: David Andres 的评论:

'“比较”不仅仅包括平等'
让我意识到我的问题不够清楚——我实际上只是在检查平等,仅此而已。

【问题讨论】:

不要担心过早的优化:使用DATEDIFF 编写您的查询,然后看看它是否是一个瓶颈或不检查查询计划。如果有问题,请寻找替代方案。 Best approach to remove time part of datetime in SQL Server的可能重复 【参考方案1】:

这样做最合理的方法是剥离日期时间值的时间部分并比较结果,而从日期时间中剥离时间部分的最佳方法是这样的:

cast(current_timestamp as date)    

我曾经使用并提倡一种类似于以下两行之一的流程:

cast(floor(cast(getdate() as float)) as datetime)
dateadd(dd,0, datediff(dd,0, getDate()))

但是现在 Sql Server 具有 Date 类型,它不包含时间组件,没有理由使用其中任何一种技术。

要记住的另一件事是,如果您需要为 where 子句或连接条件中的每一行的两个日期时间值执行此操作,这仍然会使查询陷入困境。如果可能,您希望以某种方式将其分解,以便尽可能多地预先计算,例如使用视图或计算列。

最后,请注意 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' 之间的天数中的 DATEDIFF 仍然为零,即使经过了 86,398 秒。它根本不关心那里的时间部分,只关心边界。根据您的查询尝试执行的操作,您也许可以利用它来发挥自己的优势。

【讨论】:

这不会比只使用 DATEDIFF(day, date1, date2) 效率低吗? 我并不是真的在寻找一种去掉时间的方法,而是一种在忽略时间的情况下比较两个日期的方法。这对我来说看起来有点慢.. 我所说的“其他”方法是一个计算列,它使用数据时间列上的时间剥离代码进行计算。这将使 sql server 提前完成所有工作,所以你可以说'DateA - DateB' 持久化计算列会提前完成,视图和计算列只会按需完成 您也可以使用“索引”视图来预先完成工作。【参考方案2】:

WHERE DATEDIFF(day, date1, date2)=0

【讨论】:

【参考方案3】:

在我自己的工作中,当我想确定两个日期是否相等而与一天中的时间无关时,我使用了以下方法:

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

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

但是……它确实有效。

【讨论】:

【参考方案4】:

如果您的数据模型不能很好地满足您的业务需求之一(例如,您需要比较日期,但您没有跟踪日期,只跟踪日期加时间),请查看调整模型的可能性,而不是处理它的方法。

是否可以将仅日期存储在索引计算列中,或者单独存储日期和时间部分?

【讨论】:

【参考方案5】:

抱歉回复晚了。

我总是使用这种语法进行日期比较

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

每当我们使用 112 格式代码转换日期时,它总是很有效,它以 yyyyMMdd 格式返回日期。它在没有时间的情况下比较字符串格式的日期,但效果很好。谢谢

【讨论】:

您的解决方案适用于我正在编写的脚本,而“IF date_column != GETDATE()”却没有。你知道这是为什么吗?

以上是关于在 T-SQL 中比较日期,忽略时间部分的主要内容,如果未能解决你的问题,请参考以下文章

没有时间部分的日期时间比较?

使用 T-SQL 获取日期时间的时间?

将日期字符串与 SQL Server 中的日期时间进行比较?

按连续日期分组,忽略 SQL 中的周末

如何在 SQL Server 2008 的 where 子句中仅比较日期并忽略时间

在 T-SQL 中检查两个日期之间的日期