SQL中BETWEEN子句的真正目的是什么?

时间:2013-01-13 15:48:10

标签: sql sql-server tsql

为了正确使用索引,必须将过滤谓词设为搜索参数,因此在这种情况下不能使用DATETIME函数。

您需要使用<=>=个操作数进行日期和时间比较,但也有BETWEEN子句。

所以,建议是使用简单的算术操作数,因为BETWEEN有结束日期的问题。

是否有BETWEEN优于<=>=的上下文?

4 个答案:

答案 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错误。