为了正确使用索引,您必须将过滤谓词作为搜索参数,因此在这种情况下您不能使用DATETIME
函数。
您需要使用<=
and>=
操作数进行日期和时间比较,但也有BETWEEN
子句。
因此,建议使用简单的算术操作数,因为BETWEEN
结束日期有问题。
有没有比andBETWEEN
更可取的上下文?<=
>=
为了正确使用索引,您必须将过滤谓词作为搜索参数,因此在这种情况下您不能使用DATETIME
函数。
您需要使用<=
and>=
操作数进行日期和时间比较,但也有BETWEEN
子句。
因此,建议使用简单的算术操作数,因为BETWEEN
结束日期有问题。
有没有比andBETWEEN
更可取的上下文?<=
>=
如果您问两者之间是否有任何区别
where X between 1 and 10
相对
where X >= 1 and X <= 10
那么不,没有区别。它只是对语言的一种方便的增强,是许多试图让生活更轻松的语言之一;一个BETWEEN
表达式非常清楚地表达了期望的结果。
它类似于COALESCE
函数,它只是编写CASE
检查NULL
值的表达式的一种更快捷的方法。
因此,建议使用简单的算术操作数,因为 BETWEEN 有 end dates 的问题。
不。BETWEEN 对结束日期(对于日期和时间值)没有问题,但开发人员因为有些人忘记了日期和时间(DATETIME数据类型)值也有时间组件。
所以,写
SELECT ...
FROM MyTable
WHERE MyDateTimeColumn BETWEEN '20130101' AND '20130113'
当您想显示这两个日期之间的所有记录时是错误的,因为'20130113'
表示'20130113 00:00:00.000'
(而不是'20130113 23:59:59.997'
)和BETWEEN '20130101' AND '20130113'
表示BETWEEN '20130101' AND '20130113 00:00:000.000'
。
一些解决方案:
1)
SELECT ...
FROM MyTable
WHERE MyDateTimeColumn BETWEEN '20130101' AND '20130113 23:59:59.997'
2)
SELECT ...
FROM MyTable
WHERE CONVERT(DATE, MyDateTimeColumn) BETWEEN '20130101' AND '20130113'
3)
DECLARE @StartDate DATETIME = '20120103'
DECLARE @EndDate DATETIME = '20120103'
SET @EndDate = DATEADD(MILLISECOND, -3, DATEADD(DAY, 0, DATEDIFF(DAY, 0, @EndDate)+1))
SELECT @StartDate AS [SD], @EndDate [ED]
SELECT ...
FROM MyTable
WHERE MyDateTimeColumn BETWEEN @StartDate AND @EndDate
结果:
SD ED
----------------------- -----------------------
2012-01-03 00:00:00.000 2012-01-03 23:59:59.997
(1 row(s) affected)
...
注意:DATETIME
值“四舍五入到 0.000、0.003 或 0.007 秒的增量”。
使用数字类型时,它有利于提高可读性。
如果您需要检查两个整数值之间的整数列值:
theColumn BETWEEN 5 and 25
BETWEEN 被翻译成两个单独的操作,用 or 连接:a BETWEEN b AND c
相当于a >= B AND a <= c
. 在这种情况下,等价意味着功能上的等价。它将在优化器和执行引擎中产生相同的行为。
问题在于自然语言中的单词之间是模糊的。是否意味着包含或不包含边界取决于许多并不总是显而易见的因素。我们需要远离编程的模糊行为。
虽然 T-SQL BETWEEN 具有明确定义的行为,但很容易忘记它是哪一个。由于代码的阅读频率远高于编写代码的频率,因此使其尽可能具有可读性很重要。每次读者遇到 BETWEEN 关键字时,他都必须停下来思考边界行为。这会分散注意力,也会导致难以找到错误。
您听说日期计算中的结束边界存在问题的原因是,人们最常错误地使用 BETWEEN 就是这种情况。