在SQL Server中,对带有毫秒的datetime字段的查询给出了错误的结果
我在SQLServer2005中使用datetime字段时遇到了一个奇怪的错误。datetime字段以毫秒级的精度显示,但看起来并不总是使用毫秒。以下是我的测试查询:在SQL Server中,对带有毫秒的datetime字段的查询给出了错误的结果,sql,sql-server-2005,datetime,Sql,Sql Server 2005,Datetime,我在SQLServer2005中使用datetime字段时遇到了一个奇怪的错误。datetime字段以毫秒级的精度显示,但看起来并不总是使用毫秒。以下是我的测试查询: SELECT col1, YEAR(col1) AS yr, MONTH(col1) AS mn, DAY(col1) AS dy FROM mytable WHERE col1 >= '2009-12-31 00:00:00.0' AND col1 <= '2009-12-31 23:59:59.999' ORDER
SELECT col1, YEAR(col1) AS yr, MONTH(col1) AS mn, DAY(col1) AS dy
FROM mytable
WHERE col1 >= '2009-12-31 00:00:00.0' AND col1 <= '2009-12-31 23:59:59.999'
ORDER BY col1
选择col1,年(col1)为年,月(col1)为mn,日(col1)为dy
从mytable
其中col1>='2009-12-31 00:00:00.0'和col1SQL Server
将时间部分存储为从午夜开始的1/300
秒长的滴答数
23:59:59.999
四舍五入到最接近的勾号,正好是第二天的00:00:00.000
SELECT CAST(CAST('2009-12-01 00:00:00.000' AS DATETIME) AS BINARY(8)),
CAST(CAST('2009-12-01 23:59:59.997' AS DATETIME) AS BINARY(8)),
CAST(CAST('2009-12-01 23:59:59.999' AS DATETIME) AS BINARY(8))
0x00009B8F 00000000 0x00009B8F 018B81FF 0x00009B90 00000000
在第一个值中,日期部分0x9B8F
(39823
)是自1900年1月1日以来的天数,时间部分0
是自午夜以来的节拍数
在第二个值中,0x018B81FF
(25919999
,或24*60*60*300-1
)是自午夜以来可能出现的最大滴答声数
最后,第三个值的时间部分为0
,日期部分增加1。这不是错误。这完全是意料之中的行为。
看这里:
你应该把它改成
WHERE col1 >= '2009-12-31 00:00:00.0' AND col1 < '2010-01-01'
其中col1>='2009-12-31 00:00:00.0'和col1<'2010-01-01'
对于所有浮点类型,日期/时间实际上是一种浮点值,您应该尽量避免这样的相等比较
因此,不是:
WHERE x <= 10.999
其中x这也是为什么不建议对日期使用“Between”比较运算符的原因Between'是一种包含性比较(包括两端匹配的值),如上所述,您应该执行Between的独占版本,例如
bottomvalue如果它是代码中的一个选项,请使用少于:" ... 和col1<'2010-1-1 00:00:00.0'只是为了添加参考:精度:四舍五入为增量.000、.003或.007秒
3.33毫秒。我想知道他们究竟为什么选择了那个?如果将其存储为32位日期和32位时间,则一天中的总毫秒数仅为0x05265c00,这是一个32位整数,有足够的空间。SQL Server 2008具有DATETIME2或time,可存储精度低至100ns的时间,以备不时之需。
WHERE x <= 10.999
WHERE x < 11
WHERE ... col1 < '2010-01-01 00:00:00.000'
^
| ^-- changed to 2010
^-- changed <= to <