SQL Server 2008 BETWEEN 函数

Posted

技术标签:

【中文标题】SQL Server 2008 BETWEEN 函数【英文标题】:SQL Server 2008 BETWEEN function 【发布时间】:2016-01-14 18:23:57 【问题描述】:

这是我的代码:

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 年 1 月 1 日午夜之后添加几分之一秒,我就会得到预期的 'not between' 结果。

【问题讨论】:

尝试使用 DATETIME2(3) 作为您的数据类型 - 它会起作用。从 SQL Server 2008 开始,我建议尽可能使用 DATETIME2(3) 而不是 DATETIME 【参考方案1】:

查看datetime type 的文档。在Rounding of datetime Fractional Second Precision 部分,您将找到问题的解释:

日期时间值四舍五入为 .000、.003 或 .007 的增量 秒,如下表所示。

这意味着如果你有 1 毫秒,它实际上是四舍五入到 0 毫秒,所以你的结果是is between。不幸的是,datetime 数据类型就是这样工作的,对此您无能为力,除非您可以使用其他数据类型,例如 datetime2

【讨论】:

臭得像烂肉!那么一个机构如何在一个日历年内获得所有的 val,直到最后一毫秒?当然,这是可能的,但它一定很笨拙。 @B.ClayShannon DateTime2DateTimeOffset 为您提供这种灵活性 感谢 dotnetom 的回答。所以这是“必要的妥协”。【参考方案2】:

如果您使用下面的代码,您会发现问题出在日期时间类型上。查看有关 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

【讨论】:

以上是关于SQL Server 2008 BETWEEN 函数的主要内容,如果未能解决你的问题,请参考以下文章

sql server BETWEEN and

SQL Server 索引如何帮助将 BETWEEN 用于给定查询

SQL Server 中的“BETWEEN”函数是不是非常昂贵?

Datatypes translation between Oracle and SQL Server

SQL Server: Difference between PARTITION BY and GROUP BY

SQL Server 查询使用 BETWEEN 过滤器带来不匹配的数据