MS SQL Server“之间”是否包含范围边界?

时间:2009-04-14 22:35:20

标签: sql sql-server between

例如可以

SELECT foo
FROM bar
WHERE foo BETWEEN 5 AND 10

选择5和10还是它们被排除在范围之外?

8 个答案:

答案 0 :(得分:248)

BETWEEN运算符是包含在内的。

来自联机丛书:

  

BETWEEN如果值为,则返回TRUE   test_expression大于或   等于begin_expression的值   并且小于或等于   end_expression具有

日期时间警告

注意:使用DateTimes你必须要小心;如果仅给出日期,那么该值是在当天的午夜时截取的;为了避免在结束日期内丢失时间,或者在多个范围内的午夜重复捕获第二天的数据,您的结束日期应该是在您到目前为止的第二天午夜之前的3毫秒。 3毫秒,因为任何小于此值,该值将被四舍五入到第二天的午夜。

e.g。要获得2016年6月内的所有价值,您需要运行:

where myDateTime between '20160601' and DATEADD(millisecond, -3, '20160701')

where myDateTime between '20160601 00:00:00.000' and '20160630 23:59:59.997'

datetime2和datetimeoffset

从日期减去3毫秒将使您容易在3毫秒窗口中丢失行。正确的解决方案也是最简单的解决方案:

where myDateTime >= '20160601' AND myDateTime < '20160701'

答案 1 :(得分:248)

是的,但在日期之间使用时要小心。

BETWEEN '20090101' AND '20090131'

实际上被解释为12am,或

BETWEEN '20090101 00:00:00' AND '20090131 00:00:00'

因此将错过1月31日当天发生的任何事情。在这种情况下,您将不得不使用:

myDate >= '20090101 00:00:00' AND myDate < '20090201 00:00:00'  --CORRECT!

BETWEEN '20090101 00:00:00' AND '20090131 23:59:59' --WRONG! (see update!)

更新:完全有可能在当天的最后一秒创建记录,日期时间最晚为20090101 23:59:59.997 !!

出于这个原因,不建议使用BETWEEN (firstday) AND (lastday 23:59:59)方法。

改为使用myDate >= (firstday) AND myDate < (Lastday+1)方法。

article on this issue here

答案 2 :(得分:16)

来自SQL Server 2008的真实示例。

来源数据:

ID    Start
1     2010-04-30 00:00:01.000
2     2010-04-02 00:00:00.000
3     2010-05-01 00:00:00.000
4     2010-07-31 00:00:00.000

查询:

SELECT
    *
FROM
    tbl
WHERE
    Start BETWEEN '2010-04-01 00:00:00' AND '2010-05-01 00:00:00'

结果:

ID    Start
1     2010-04-30 00:00:01.000
2     2010-04-02 00:00:00.000

alt text

答案 3 :(得分:13)

如果你点击这个,并且真的不想尝试在代码中添加一天,那就让DB去做吧..

myDate >= '20090101 00:00:00' AND myDate < DATEADD(day,1,'20090101 00:00:00')

如果你确实包括时间部分:确保它引用午夜。否则你可以简单地省略时间:

myDate >= '20090101' AND myDate < DATEADD(day,1,'20090101')

而不用担心。

答案 4 :(得分:12)

  

BETWEEN(Transact-SQL)

     

指定要测试的( n )(包含)范围。

test_expression [ NOT ] BETWEEN begin_expression AND end_expression
  

<强>参数

test_expression
     

表达式是否在begin_expression定义的范围内进行测试   和end_expression。与test_expression   必须与两者的数据类型相同   begin_expression和end_expression。

NOT
     

指定谓词的结果被否定。

begin_expression
     

是否有效表达。 begin_expression必须是相同的数据   键入test_expression和   end_expression具有

end_expression
     

是否有效表达。 end_expression必须是相同的数据   键入test_expression和   与begin_expression。

AND
     

充当占位符,指示test_expression应该是   在指定的范围内   begin_expression和end_expression。

     

<强>说明

     

要指定独占范围,请使用   大于(&gt;)且小于   运算符(&lt;)。如果有任何输入   在谓词之间或之间没有   NULL,结果是UNKNOWN。

     

结果值

     

BETWEEN如果值为,则返回TRUE   test_expression大于或   等于begin_expression的值   并且小于或等于   end_expression具有

     

NOT BETWEEN如果值,则返回TRUE   test_expression小于   begin_expression或更高的值   比end_expression的值。

答案 5 :(得分:3)

如果列数据类型是datetime,那么您可以执行以下操作以消除日期时间,并仅比较日期范围。

where cast(getdate() as date) between cast(loginTime as date) and cast(logoutTime as date)

答案 6 :(得分:0)

确实包括边界。

declare @startDate date = cast('15-NOV-2016' as date) 
declare @endDate date = cast('30-NOV-2016' as date)
create table #test (c1 date)
insert into #test values(cast('15-NOV-2016' as date))
insert into #test values(cast('20-NOV-2016' as date))
insert into #test values(cast('30-NOV-2016' as date))
select * from #test where c1 between @startDate and @endDate
drop table #test
RESULT    c1
2016-11-15
2016-11-20
2016-11-30


declare @r1 int  = 10
declare @r2 int  = 15
create table #test1 (c1 int)
insert into #test1 values(10)
insert into #test1 values(15)
insert into #test1 values(11)
select * from #test1 where c1 between @r1 and @r2
drop table #test1
RESULT c1
10
11
15

答案 7 :(得分:-3)

我一直用这个:

myDate BETWEEN startDate AND(endDate + 1)