SQL查询:比较两个表的datetime2字段时如何忽略纳秒?
嗨,这个问题我之前处理过,其实核心就是把两个datetime2值统一截断到毫秒级别再做对比就行,给你几种实用的实现方法:
方法1:直接转换为毫秒精度的datetime2(3)
这是最直观的方式,利用datetime2的精度参数(3代表保留到毫秒),把两个字段都转换后再对比:
select t1.* from Table1 t1, Table2 t2 where CAST(t1.tradeDateTime AS datetime2(3)) = CAST(t2.tradeDate AS datetime2(3))
原理很简单:datetime2(3)会自动截断毫秒之后的纳秒部分,这样你示例里的2018-01-24 10:51:23.9976180就会变成2018-01-24 10:51:23.997,和Table2里的对应值完全匹配。
方法2:用DATEADD+DATEDIFF截断毫秒以下部分
如果习惯用日期函数的写法,也可以通过计算从基准时间到目标时间的毫秒数,再还原成日期来截断:
select t1.* from Table1 t1, Table2 t2 where DATEADD(ms, DATEDIFF(ms, 0, t1.tradeDateTime), 0) = DATEADD(ms, DATEDIFF(ms, 0, t2.tradeDate), 0)
这里的0代表SQL Server的基准日期1900-01-01 00:00:00,DATEDIFF(ms, 0, ...)会计算出从基准日期到目标时间的总毫秒数,再用DATEADD把这个毫秒数加回基准日期,就自动去掉了毫秒以下的部分。
性能优化提示(如果数据量较大)
如果你的表数据量不小,直接在字段上用函数会导致索引失效,查询变慢。这时候可以考虑给Table1加一个持久化计算列,并创建索引:
-- 给Table1添加持久化的毫秒级日期列 ALTER TABLE Table1 ADD tradeDateTime_ms AS CAST(tradeDateTime AS datetime2(3)) PERSISTED; -- 给计算列创建索引 CREATE INDEX IX_Table1_tradeDateTime_ms ON Table1(tradeDateTime_ms);
之后查询时就可以用这个计算列来对比,能充分利用索引提升性能:
select t1.* from Table1 t1, Table2 t2 where t1.tradeDateTime_ms = CAST(t2.tradeDate AS datetime2(3))
另外你提到只是测试JOIN写法,正式使用时记得改成规范的INNER JOIN语法哦,比如:
select t1.* from Table1 t1 INNER JOIN Table2 t2 ON CAST(t1.tradeDateTime AS datetime2(3)) = CAST(t2.tradeDate AS datetime2(3))
内容的提问来源于stack exchange,提问作者XtremeBaumer
相关产品推荐
相关产品推荐

