SQL Server 2008 BETWEEN函数

5

这是我的代码:

DECLARE @d1 DATETIME
DECLARE @d2 DATETIME

SET @d1 = '2015-01-01 00:00:00'
SET @d2 = '2015-12-31 23:59:59.999'

SELECT 
    CASE 
       WHEN ('2016-01-01 00:00:00' BETWEEN @d1 AND @d2) 
          THEN 'is between' 
          ELSE 'not between'
    END  AS BetweenOrNotBetween

我提供的日期比“BETWEEN”函数的范围晚1毫秒,但在我的SQL 2008服务器实例上,结果是“is between”,而不是预期的“not between”。这是一个错误吗?还是因为某种原因在设计中必须做出妥协,我没有看到?是的,一旦我添加了2016-01-01午夜之后的甚至一小部分时间,我就会得到预期的“not between”结果。

1
尝试使用DATETIME2(3)作为数据类型进行相同的操作 - 它会起作用。从SQL Server 2008开始,我建议您尽可能使用DATETIME2(3)而不是DATETIME - marc_s
2个回答

7
请参考datetime类型的文档。在“Rounding of datetime Fractional Second Precision”章节中,您将找到解释您问题的内容:

datetime值被舍入为.000、.003或.007秒的增量,如下表所示。

这意味着如果您有1毫秒,它实际上会被舍入为0毫秒,因此您的结果介于之间。不幸的是,这就是datetime数据类型的工作方式,除非您可以使用其他数据类型(例如datetime2),否则无法做太多事情。

那真是臭的像腐烂的肉!那么,一个程序该如何获取一年中所有日期的值,直到最后一毫秒?当然,这是可能的,但一定很笨拙。 - B. Clay Shannon-B. Crow Raven
2
@B.ClayShannon DateTime2DateTimeOffset可以为您提供这种灵活性。 - JamieD77
感谢您的回答,dotnetom。所以这就是“必要的妥协”了。 - Steve L

2
如果您使用下面的代码,您会发现问题出在datetime类型上。查看有关datetime的文档,您的疑惑将得到解决!
DECLARE @d1 datetime2
DECLARE @d2 datetime2

SET @d1 = '2015-01-01 00:00:00.00'
SET @d2 = '2015-12-31 23:59:59.999'

SELECT CASE WHEN ('2016-01-01 00:00:00.00' BETWEEN @d1 AND @d2 ) THEN 'is between' 
       ELSE 'not between'
       END  AS BetweenOrNotBetween

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接