为了正确使用索引,必须将过滤谓词设为搜索参数,因此在这种情况下不能使用DATETIME
函数。
您需要使用<=
和>=
个操作数进行日期和时间比较,但也有BETWEEN
子句。
所以,建议是使用简单的算术操作数,因为BETWEEN
有结束日期的问题。
是否有BETWEEN
优于<=
和>=
的上下文?
答案 0 :(得分:6)
如果您询问
之间是否存在任何差异where X between 1 and 10
与
where X >= 1 and X <= 10
然后没有,没有区别。它只是对语言的一种方便的增强,是许多试图让生活更轻松的语言之一; BETWEEN
表达式非常清楚地表达了期望的结果。
它与COALESCE
函数类似,这只是编写检查CASE
值的NULL
表达式的更快捷方式。
答案 1 :(得分:4)
所以,建议是使用简单的算术操作数,因为 BETWEEN的结束日期有问题。
没有。 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
值为"rounded to increments of .000, .003, or .007 seconds"。
答案 2 :(得分:1)
使用数字类型时,这对于可读性是有益的。
如果需要检查两个整数值之间的整数列值:
theColumn BETWEEN 5 and 25
答案 3 :(得分:1)
BETWEEN被转换为与or连接的两个单独的操作:a BETWEEN b AND c
相当于a >= B AND a <= c
。在此上下文中的等效意味着在功能上等同。它将在优化器和执行引擎中产生相同的行为。
问题在于自然语言之间的单词是模糊的。如果含有或不含有边界,则取决于许多并不总是显而易见的因素。我们需要远离编程的模糊行为。
虽然T-SQL BETWEEN具有明确定义的行为,但很容易忘记它是哪一个。因为代码的读取频率比写入的频率高得多,所以尽可能使代码具有可读性非常重要。每次读者遇到BETWEEN关键字时,他都必须停下来思考边界行为。这会分散注意力,也很难找到错误。
您听说日期计算中的结束边界存在问题的原因是,人们最经常使用BETWEEN错误。