Si ejecuto una consulta con una between
cláusula, parece excluir el valor final.
Por ejemplo:
select * from person where dob between '2011-01-01' and '2011-01-31'
Esto obtiene todos los resultados dob
desde '2011-01-01' hasta '2011-01-30'; saltando registros donde dob
es '2011-01-31'. ¿Alguien puede explicar por qué esta consulta se comporta de esta manera y cómo podría modificarla para incluir registros donde dob
está '2011-01-31'? (sin agregar 1 a la fecha de finalización porque ha sido seleccionado por los usuarios).
BETWEEN
Incluye ambos valores. TengoMySQL Server 5.7
en Windows 10.Respuestas:
El campo
dob
probablemente tiene un componente de tiempo.Para truncarlo:
fuente
CAST(dob AS DATE)
usted puede usar el más sucintoDATE(dob)
.>=
y en<
lugar debetween
.dob BETWEEN '2011-01-01 00:00:00' AND '2011-01-31 23:59:59
. Esto se debe a queDATE(dob)
tiene que calcular un valor para cada fila y no puede usar ningún índice en ese campo.t > 23:59:59 and t < 24:00:00
. ¿Por qué tratar con poco especificadoBETWEEN
? Más bien seguir el consejo y el uso de David:WHERE dob >= '2011-01-01' AND dob < '2011-02-01'
. El mejor rendimiento, y funciona todo el tiempo.Del manual de MySQL :
fuente
El problema es que 2011-01-31 realmente es 2011-01-31 00:00:00. Ese es el comienzo del día. Todo durante el día no está incluido.
fuente
fuente
2011-01-31 23:59:59
que se incluyen los que hasta2011-01-31 23:59:58
el último segundo del día no se incluye Podría ser menor, pero alguien va a beneficiar.23:59:59
en el resultado. Por lo tanto, sus dos sentidos son inclusivos.dob
columna es una marca de tiempo con una precisión inferior al segundo, ¿no seBETWEEN
perderán eventos en el último segundo del día a menos que se use '2011-02-01 00:00:00'?2011-01-31 23:59:59.003
. @nitrogen usando2011-02-01 000:00:00
habrá incorrectamente incluir el tiempo cero el 1 de febrero .... ¿Cuál es la razón>=
y<
se debe utilizar en su lugar.¿El campo al que hace referencia en su consulta es un tipo de fecha o un tipo de fecha y hora ?
Una causa común del comportamiento que describe es cuando usa un tipo DateTime donde realmente debería estar usando un tipo Date. Es decir, a menos que realmente necesite saber a qué hora nació alguien, simplemente use el tipo Fecha.
La razón por la que el último día no se incluye en sus resultados es la forma en que la consulta asume la parte de tiempo de las fechas que no especificó en su consulta.
Es decir: su consulta se interpreta como hasta la medianoche entre el 30/01/2011 y el 31-01-2011, pero los datos pueden tener un valor en algún momento más tarde en el día 31/01/2011.
Sugerencia: cambie el campo al tipo Fecha si es un tipo Fecha y hora.
fuente
Hola, esta consulta me funciona,
fuente
Sorprendentemente, tales conversiones son soluciones a muchos problemas en MySQL.
fuente
Establezca la fecha superior en fecha + 1 día, por lo tanto, en su caso, configúrelo en 2011-02-01.
fuente
BETWEEN
debe ignorarse; pero>=
y<
debería usarse en su lugar.Puede ejecutar la consulta como:
como otros señalaron, si sus fechas están codificadas.
Por otro lado, si la fecha está en otra tabla, puede agregar un día y restar un segundo (si las fechas se guardan sin el segundo / hora), como:
Evite realizar lanzamientos en los
dob
campos (como en la respuesta aceptada), porque eso puede causar grandes problemas de rendimiento (como no poder usar un índice en eldob
campo, suponiendo que haya uno). El plan de ejecución puede cambiar deusing index condition
ausing where
si haces algo comoDATE(dob)
oCAST(dob AS DATE)
, ¡así que ten cuidado!fuente
En MySql, los valores son inclusivos, por lo tanto, cuando intenta obtener entre '2011-01-01' y '2011-01-31'
incluirá desde
2011-01-01 00:00:00
hasta2011-01-31 00:00:00
por lo tanto, nada en realidad en 2011-01-31 ya que su tiempo debería pasar de2011-01-31 00:00:00 ~ 2011-01-31 23:59:59
Para el límite superior puede cambiar a,
2011-02-01
entonces obtendrá todos los datos hasta2011-01-31 23:59:59
fuente