not - ¿El "entre" de MS SQL Server incluye los límites del rango?
sql server between dates (8)
BETWEEN (Transact-SQL)
Especifica un ( n ) rango ( inclusivo ) para probar.
test_expression [ NOT ] BETWEEN begin_expression AND end_expression
Argumentos
test_expression
Es la expresión a probar en el rango definido por begin_expression y end_expression. test_expression debe ser el mismo tipo de datos que begin_expression y end_expression.
NOT
Especifica que el resultado del predicado sea negado.
begin_expression
Es cualquier expresión válida. begin_expression debe ser el mismo tipo de datos que test_expression y end_expression.
end_expression
Es cualquier expresión válida. end_expression debe ser el mismo tipo de datos que tanto test_expression como begin_expression.
AND
Actúa como un marcador de posición que indica que test_expression debe estar dentro del rango indicado por begin_expression y end_expression.
Observaciones
Para especificar un rango exclusivo, utilice los operadores mayor que (>) y menor que (<). Si alguna entrada al predicado BETWEEN o NOT BETWEEN es NULL, el resultado es UNKNOWN.
Valor del resultado
BETWEEN devuelve VERDADERO si el valor de test_expression es mayor o igual que el valor de begin_expression y menor o igual que el valor de end_expression.
NOT BETWEEN devuelve TRUE si el valor de test_expression es menor que el valor de begin_expression o mayor que el valor de end_expression.
Por ejemplo puede
SELECT foo
FROM bar
WHERE foo BETWEEN 5 AND 10
¿Seleccionar 5 y 10 o están excluidos del rango?
Ejemplo del mundo real de SQL Server 2008.
Datos fuente:
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
Consulta:
SELECT
*
FROM
tbl
WHERE
Start BETWEEN ''2010-04-01 00:00:00'' AND ''2010-05-01 00:00:00''
Resultados:
ID Start
1 2010-04-30 00:00:01.000
2 2010-04-02 00:00:00.000
El operador BETWEEN es inclusivo.
De los libros en línea:
BETWEEN devuelve VERDADERO si el valor de test_expression es mayor o igual que el valor de begin_expression y menor o igual que el valor de end_expression.
DateTime Caveat
NB: Con DateTimes tienes que tener cuidado; si solo se da una fecha, el valor se toma a partir de la medianoche de ese día; para evitar tiempos perdidos dentro de su fecha de finalización, o repetir la captura de los datos del día siguiente a la medianoche en varios rangos, su fecha de finalización debe ser de 3 milisegundos antes de la medianoche del día siguiente a su fecha. 3 milisegundos porque un poco menos que esto y el valor se redondearán hasta la medianoche del día siguiente.
Por ejemplo, para obtener todos los valores en junio de 2016, debe ejecutar:
where myDateTime between ''20160601'' and DATEADD(millisecond, -3, ''20160701'')
es decir
where myDateTime between ''20160601 00:00:00.000'' and ''20160630 23:59:59.997''
datetime2 y datetimeoffset
Restar 3 ms de una fecha lo dejará vulnerable a las filas faltantes de la ventana de 3 ms. La solución correcta es también la más sencilla:
where myDateTime >= ''20160601'' AND myDateTime < ''20160701''
Incluye límites.
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
Sí, pero tenga cuidado al usar entre las fechas.
BETWEEN ''20090101'' AND ''20090131''
realmente se interpreta como 12 am, o
BETWEEN ''20090101 00:00:00'' AND ''20090131 00:00:00''
así se perderá todo lo ocurrido durante el día 31 de enero. En este caso, deberás utilizar:
myDate >= ''20090101 00:00:00'' AND myDate < ''20090201 00:00:00'' --CORRECT!
o
BETWEEN ''20090101 00:00:00'' AND ''20090131 23:59:59'' --WRONG! (see update!)
ACTUALIZACIÓN : ¡Es completamente posible tener registros creados en ese último segundo del día, con una fecha tan tardía como 20090101 23:59:59.997
!
Por esta razón, no se recomienda el enfoque BETWEEN (firstday) AND (lastday 23:59:59)
.
Utilice el myDate >= (firstday) AND myDate < (Lastday+1)
lugar.
Si el tipo de datos de la columna es datetime, puede hacer lo siguiente para eliminar el tiempo de datetime y comparar solo entre el rango de fechas.
where cast(getdate() as date) between cast(loginTime as date) and cast(logoutTime as date)
Si presionas esto, y realmente no quieres tratar de manejar agregar un día en código, entonces deja que el DB lo haga.
myDate >= ''20090101 00:00:00'' AND myDate < DATEADD(day,1,''20090101 00:00:00'')
Si incluye la parte de tiempo: asegúrese de que hace referencia a la medianoche. De lo contrario, simplemente puede omitir el tiempo:
myDate >= ''20090101'' AND myDate < DATEADD(day,1,''20090101'')
Y no te preocupes por eso.
Siempre he usado esto:
DONDE myDate ENTRE startDate AND (endDate + 1)