www.cftea.com

SQL Server 查询条件中,不要使用 .999 作为时间毫秒

ITPOW2020/7/22 17:39:24

考虑如下 SQL 语句:

select * from itpow where dt<='2020-07-21 23:59:59.999'

我们会发现 22 日零点的数据也会被查询出来,为什么呢?

因为:datetime 的小数秒精度精确到三百分之一秒(相当于 3.33 毫秒或 0.00333 秒)。值舍入到 .000、.003 或 .007 秒三个增量。

原来 999 越界了,被收上去了,就变成 22 日了。

所以我们只能写到 998。

具体规则

上述文档中微软使用的“增量”太误导人,实际就是指最后一位往 0、3、7 上靠,其中 5 位于 3、7 中间,往 7 靠。

0.000 -> 0.000

0.001 -> 0.000

0.002 -> 0.003

0.003 -> 0.003

0.004 -> 0.003

0.005 -> 0.007

0.006 -> 0.007

0.007 -> 0.007

0.008 -> 0.007

0.009 -> 0.010


0.010 -> 0.010

0.011 -> 0.010

0.012 -> 0.013

0.013 -> 0.013

0.014 -> 0.013

0.015 -> 0.017

0.016 -> 0.017

0.017 -> 0.017

0.018 -> 0.017

0.019 -> 0.020

扩展

SQL Server 文档中说,字符串隐式转换成 datetime、datetime2 时,支持 SQL 标准格式 YYY-MM-DD hh:mi:ss.[nnnnnnn]

这里有 7 个 n,然而,datetime 在应用第 4 个 n 时就会提示:从字符串转换日期和/或时间时,转换失败。其实 datetime 精度本来就没那么高,超过 3 位即使能转换,也是没有意义的。

也就是说 SQL Server 文档那里,其实应该分开说:

  • datetime 3 个 n。

  • datetime2 7 个 n。

另外文档中提到了 ISO 8601 格式,这个格式:日期、时间之间不是用空格隔开的,而是用 T。

比如:2020-07-22T17:54:08,但是这种格式要注意补 0,比如 7 那里,如果我们不补 0,就会出错。

<<返回首页<<