Включает ли “between” MS SQL Server границы диапазона?

StackOverflow https://stackoverflow.com/questions/749615

  •  09-09-2019
  •  | 
  •  

Вопрос

Например, может

SELECT foo
FROM bar
WHERE foo BETWEEN 5 AND 10

выберите 5 и 10 или они исключены из диапазона?

Это было полезно?

Решение

Оператор BETWEEN является включительным.

Из книг Онлайн:

BETWEEN возвращает значение TRUE, если значение test_expression больше или равно значению begin_expression и меньше или равно значению end_expression.

Оговорка о дате и времени

ПРИМЕЧАНИЕ:С датами и временем вы должны быть осторожны;если задана только дата, то значение берется по состоянию на полночь этого дня;чтобы избежать пропусков времени в вашей конечной дате или повторения сбора данных на следующий день в полночь в нескольких диапазонах, ваша конечная дата должна быть за 3 миллисекунды до полуночи следующего за вашей даты "до" дня.3 миллисекунды, потому что любое значение меньше этого, и значение будет округлено до полуночи следующего дня.

например ,чтобы получить все значения в течение июня 2016 года, вам нужно будет запустить:

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 datetimeoffset

Вычитание 3 мс из даты сделает вас уязвимым к отсутствию строк в окне 3 мс.Правильное решение также является самым простым:

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

Другие советы

Да, но будьте осторожны при использовании between для обозначения дат.

BETWEEN '20090101' AND '20090131'

на самом деле интерпретируется как 12 утра, или

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

так что будем пропускать все, что произошло в течение дня 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) вместо этого подойдите.

Хорошо статья по этому вопросу здесь.

Реальный пример из 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

если вы столкнулись с этим и на самом деле не хотите пытаться обрабатывать добавление дня в коде, то позвольте базе данных сделать это..

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

Если вы включаете временную часть:убедитесь, что он ссылается на полночь.В противном случае вы можете просто опустить время:

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

и не беспокойся об этом.

МЕЖДУ (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, результат НЕИЗВЕСТЕН.

Значение результата

BETWEEN возвращает значение TRUE, если значение test_expression больше или равно значению begin_expression и меньше или равно значению end_expression.

NOT BETWEEN возвращает TRUE, если значение test_expression меньше, чем значение begin_expression или больше , чем значение end_expression.

Если тип данных столбца - datetime, то вы можете сделать следующее, чтобы исключить время из datetime и сравнить только между диапазонами дат.

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

Это действительно включает в себя границы.

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

Я всегда пользовался этим:

ГДЕ myDate МЕЖДУ начальной датой И (Конечная дата + 1)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top