如何比较不同精度的datetime2值?解决舍入导致的匹配失败问题
解决datetime2比较时忽略纳秒且避免舍入问题的两种方法
针对你遇到的datetime2比较时因舍入导致结果不准确的问题,这里提供两种精准的解决方案,完全满足你的需求:
途径B:将datetime2向下取整到毫秒(替代舍入)
SQL Server默认的CAST(date AS datetime2(3))会对纳秒部分进行四舍五入,这就是你匹配失败的核心原因。要实现**向下取整(截断)**到毫秒,可以用DATEADD和DATEDIFF的组合,直接截断纳秒部分:
-- 替换YourDateTime2Column为你的字段名或具体值 SELECT DATEADD(MILLISECOND, DATEDIFF(MILLISECOND, '1970-01-01', YourDateTime2Column), '1970-01-01') AS TruncatedDateTime
示例验证
对于你的测试值2018-01-24 16:20:51.0715460,执行后会得到2018-01-24 16:20:51.0710000,和你期望的匹配值完全一致;另外两个2018-01-25 09:52:04.1946950也会被截断为2018-01-25 09:52:04.1940000,完美解决舍入问题。
途径A:获取datetime2对应的毫秒级时间戳
和Java中Date.getTime()或Timestamp.getTime()的逻辑一致,你可以直接提取datetime2值自1970-01-01 00:00:00 GMT以来的毫秒数,用数值比较完全规避日期格式的精度问题:
SELECT DATEDIFF(MILLISECOND, '1970-01-01', YourDateTime2Column) AS MillisecondsSinceEpoch
示例验证
2018-01-24 16:20:51.0715460和2018-01-24 16:20:51.0710000的毫秒数结果完全相同,直接比较这个数值就能得到准确的匹配结果,这也是跨语言(比如Java和SQL)日期比较的可靠方式。
额外说明
- 为什么
CAST(datetime2 AS datetime2(3))不行?因为SQL Server的CAST操作是四舍五入到指定精度,比如.0715460会被舍入为.072,而不是你需要的.071; - 两种方法任选其一即可:如果需要保留日期时间格式用于展示或后续日期操作,选途径B;如果只需要做等值/范围比较,途径A的数值比较更高效直接。
内容的提问来源于stack exchange,提问作者XtremeBaumer
相关产品推荐
相关产品推荐

