在 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 中比较日期,忽略时间部分的主要内容,如果未能解决你的问题,请参考以下文章
将日期字符串与 SQL Server 中的日期时间进行比较?