uso - where in range sql




O “entre” do MS SQL Server inclui os limites do intervalo? (6)

BETWEEN (Transact-SQL)

Especifica um intervalo ( n ) ( inclusive ) para teste.

test_expression [ NOT ] BETWEEN begin_expression AND end_expression

Argumentos

test_expression

É a expressão para teste no intervalo definido por begin_expression e end_expression. test_expression deve ser o mesmo tipo de dados de begin_expression e end_expression.

NOT

Especifica que o resultado do predicado seja negado.

begin_expression

É qualquer expressão válida. begin_expression deve ser o mesmo tipo de dados que test_expression e end_expression.

end_expression

É qualquer expressão válida. end_expression deve ser o mesmo tipo de dados que test_expression e begin_expression.

AND

Atua como um marcador de posição que indica que test_expression deve estar dentro do intervalo indicado por begin_expression e end_expression.

Observações

Para especificar um intervalo exclusivo, use o maior que (>) e menor que os operadores (<). Se qualquer entrada para o predicado BETWEEN ou NOT BETWEEN for NULL, o resultado será UNKNOWN.

Valor do resultado

BETWEEN retorna TRUE se o valor de test_expression for maior ou igual ao valor de begin_expression e menor ou igual ao valor de end_expression.

NOT BETWEEN retorna TRUE se o valor de test_expression for menor que o valor de begin_expression ou maior que o valor de end_expression.

Por exemplo, pode

SELECT foo
FROM bar
WHERE foo BETWEEN 5 AND 10

selecione 5 e 10 ou eles são excluídos do intervalo?


Eu sempre usei isso:

ONDE myDate ENTRE startDate E (endDate + 1)


Isso inclui limites.

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

O operador BETWEEN é inclusivo.

Dos livros online:

BETWEEN retorna TRUE se o valor de test_expression for maior ou igual ao valor de begin_expression e menor ou igual ao valor de end_expression.

Advertência de data e hora

NB: Com DateTimes você tem que ter cuidado; se apenas uma data é dada, o valor é tomado a partir da meia-noite daquele dia; Para evitar tempos ausentes em sua data de término ou repetir a captura dos dados do dia seguinte à meia-noite em vários intervalos, sua data de término deve ser de três milissegundos antes da meia-noite do dia seguinte à sua data atual. 3 milissegundos porque menos que isso e o valor será arredondado para a meia-noite do dia seguinte.

Por exemplo, para obter todos os valores em junho de 2016, você precisa executar:

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

ou seja

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

datetime2 e datetimeoffset

A subtração de 3 ms a partir de uma data deixará você vulnerável a linhas ausentes da janela de 3 ms. A solução correta também é a mais simples:

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

Se você acertar isso, e realmente não quer tentar manipular adicionando um dia no código, então deixe o DB fazer isso ..

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

Se você incluir a parte da hora: verifique se ela faz referência à meia-noite. Caso contrário, você pode simplesmente omitir a hora:

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

e não se preocupe com isso.


Sim, mas tenha cuidado ao usar entre datas.

BETWEEN '20090101' AND '20090131'

é realmente interpretado como 12h, ou

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

por isso vai sentir falta de tudo o que ocorreu durante o dia 31 de janeiro. Neste caso, você terá que usar:

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

ou

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

ATUALIZAÇÃO : É totalmente possível ter registros criados nesse último segundo do dia, com um datetime tão antigo quanto 20090101 23:59:59.997 !!

Por esse motivo, a BETWEEN (firstday) AND (lastday 23:59:59) não é recomendada.

Use a myDate >= (firstday) AND myDate < (Lastday+1) .

Bom artigo sobre esta questão aqui .





between