2009-04-14 1 views

ответ

220

Оператор BETWEEN включен.

С Books Online:

МЕЖДУ возвращает значение ИСТИНА, если значение test_expression больше или равно значению begin_expression и меньше или равно значению end_expression.

DateTime Caveat

NB: С DateTimes вы должны быть осторожными; если дана только дата, значение принимается с полуночи в этот день; чтобы избежать пропущенных времен в течение вашей конечной даты или повторить захват данных следующего дня в полночь в нескольких диапазонах, ваша дата окончания должна составлять 3 миллисекунды до полуночи следующего дня после вашего дня. 3 миллисекунды, потому что меньше, чем это, и значение будет округлено до полуночи на следующий день.

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

where myDateTime between '2016-06-01' and dateadd(millisecond, -3, '2016-07-01')

т.е.

where myDateTime between '2016-06-01 00:00:00.000' and '2016-07-01 23:59:59.997'

+5

При использовании BETWEEN для фильтрации DateTimes между двумя датами, вы можете также бросить DateTime к дате, например: где CONVERT (ДАТА, MyDate) между '2017-09-01' и «2017-09-30 «Этот подход делает элемент времени DateTime нерелевантным – Pete

10

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.

Замечания

Чтобы указать эксклюзивный ассортимент, используйте больше (>) и меньше операторов (<). Если какой-либо вход в предикат BETWEEN или NOT BETWEEN равен NULL, результат НЕИЗВЕСТНО.

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

МЕЖДУ возвращает истину, если значение test_expression больше или равно значению begin_expression и меньше или равно значению end_expression.

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

237

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

BETWEEN '01/01/2009' AND '01/31/2009' 

действительно интерпретируется как 12am или

BETWEEN '01/01/2009 00:00:00' AND '01/31/2009 00:00:00' 

так будет не хватать все, что произошло в течение дня Jan 31. В этом случае, вы должны будете использовать:

myDate >= '01/01/2009 00:00:00' AND myDate < '02/01/2009 00:00:00' --CORRECT! 

или

BETWEEN '01/01/2009 00:00:00' AND '01/31/2009 23:59:59' --WRONG! (see update!) 

UPDATE: Вполне возможно, чтобы иметь записи, созданные в этой последней секунде дня, с даты-времени, как в конце как 01/01/2009 23:59:59.997 !!

По этой причине подход BETWEEN (firstday) AND (lastday 23:59:59) не рекомендуется.

Используйте вместо этого подход myDate >= (firstday) AND myDate < (Lastday+1).

Хорошо article on this issue here.

+1

Аналогичные проблемы с строками, а также' WHERE col BETWEEN 'a' AND 'z' 'исключает, например, большую часть z-строк. –

+7

Этот вопрос, конечно, прав; но не удивительно, если вы работаете с datetime. Это похоже на то, что «BETWEEN 5 AND 10' не включает' 10.2' ... –

+4

'CAST'' 'datetime' как' DATE' будет работать: 'CAST (DATE_TIME_COL AS DATE) BETWEEN '01/01/2009 'И '01/31/2009''. – craig

16

Реальный пример мира с SQL Server 2008.

alt text

+0

+1 спасибо большое ... –

+0

Я не получил ваш ответ, если честно. Возможно, мой интернет-провайдер скрыл ваш скриншот, если вы его разместили. –

+0

@Anar, прямая ссылка на изображение http://imgur.com/sTKRO.png. –

12

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

myDate >= '01/01/2009 00:00:00' AND myDate < DATEADD(day,1,'01/01/2009 00:00:00') 
3

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

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

Обратите внимание, что это не [sargable] (http://en.wikipedia.org/wiki/Sargable). –

+0

Это работает лучше, чем добавление +1 к дате окончания. Я согласен с Эндрю Мортоном - если он не поддается продвижению, он может улучшить производительность, чтобы изменить тип данных столбца или добавить второй столбец только с заранее рассчитанными датами. – Volkirith

-2

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

ГДЕ MyDate МЕЖДУ STARTDATE И (ENDDATE + 1)

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 
Смежные вопросы