250

比如可以

SELECT foo
FROM bar
WHERE foo BETWEEN 5 AND 10

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

4

8 回答 8

274

BETWEEN 运算符是包容性的。

来自在线书籍:

如果 test_expression 的值大于或等于 begin_expression 的值且小于或等于 end_expression 的值,则 BETWEEN 返回 TRUE。

日期时间警告

注意:使用 DateTimes 你必须小心;如果只给出了一个日期,则该值取自当天的午夜;为避免在结束日期内丢失时间,或在多个范围内重复捕获第二天午夜的数据,结束日期应为截止日期后一天午夜前 3 毫秒。3 毫秒,因为任何小于此值的值将向上舍入到第二天的午夜。

例如,要在 2016 年 6 月内获取所有值,您需要运行:

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

IE

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

datetime2 和 datetimeoffset

从日期中减去 3 毫秒将使您容易受到 3 毫秒窗口中缺失行的影响。正确的解决方案也是最简单的一种:

where myDateTime >= '20160601' AND myDateTime < '20160701'
于 2009-04-14T22:36:25.440 回答
264

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

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)方法。

关于这个问题的好文章在这里

于 2009-04-14T23:00:17.097 回答
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

替代文字

于 2010-07-30T19:45:02.690 回答
13

如果您遇到了这个问题,并且真的不想尝试在代码中添加一天,那么让数据库来做吧..

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

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

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

不用担心。

于 2011-12-26T18:29:17.123 回答
12

之间(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 指示的范围内。

评论

要指定独占范围,请使用大于 (>) 和小于运算符 (<)。如果 BETWEEN 或 NOT BETWEEN 谓词的任何输入为 NULL,则结果为 UNKNOWN。

结果值

如果 test_expression 的值大于或等于 begin_expression 的值且小于或等于 end_expression 的值,则 BETWEEN 返回 TRUE。

如果 test_expression 的值小于 begin_expression 的值或大于 end_expression 的值,NOT BETWEEN 返回 TRUE。

于 2009-04-14T22:40:44.990 回答
4

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

where cast(getdate() as date) between cast(loginTime as date) and cast(logoutTime as date)
于 2014-01-30T02:57:35.940 回答
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
于 2017-02-27T13:44:23.547 回答
-3

我一直用这个:

我的日期在 startDate 和 (endDate+1) 之间

于 2015-03-24T01:32:22.187 回答