MySQL compara la cadena DATE con la cadena del campo DATETIME

93

Tengo una pregunta: ¿Es posible seleccionar de una base de datos MySQL comparando una cadena DATE "2010-04-29" con cadenas que se almacenan como DATETIME (2010-04-29 10:00)?

Tengo un selector de fecha que filtra datos y me gustaría consultar la tabla por el campo DATETIME como este:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... y me gustaría obtener la fila que tiene el valor DATETIME de "2010-04-29 10:00".

¿Alguna sugerencia? Gracias.

Manny Calavera
fuente

Respuestas:

163

Utilice lo siguiente:

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

Solo como referencia, tengo una tabla de registros de 2 millones, ejecuté una consulta similar. La respuesta de Salil tomó 4.48 segundos, la anterior tomó 2.25 segundos.

Entonces, si la mesa es GRANDE, sugeriría esto.

David
fuente
8
La primera respuesta es muy lenta, porque tiene que formatear cada fecha y hora en una cadena antes de la comparación. Tu es mejor, porque compara directamente solo la parte de la fecha del campo, pero aún no puede usar el índice (probado en mysql 5.1)
Marki555
1
Si el rendimiento es un problema, podría valer la pena considerar almacenar la parte de la fecha y la hora por separado, de modo que se pueda colocar un INDICE en la parte de la fecha.
Thijs Riezebeek
1
Esta consulta no podrá usar index si startTimeestá indexada.
Zamrony P. Juhara
43

Si desea seleccionar todas las filas donde la parte DATE de una columna DATETIME coincide con un cierto literal, no puede hacerlo así:

WHERE startTime = '2010-04-29'

porque MySQL no puede comparar un DATE y un DATETIME directamente. Lo que hace MySQL, extiende el literal DATE dado con el tiempo '00: 00: 00 '. Entonces tu condición se vuelve

WHERE startTime = '2010-04-29 00:00:00'

¡Ciertamente no es lo que quieres!

La condición es un rango y, por lo tanto, debe darse como rango. Hay varias posibilidades:

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

Existe una pequeña posibilidad de que el primero se equivoque, cuando su columna DATETIME usa una resolución de subsegundos y hay una cita a las 23:59:59 + épsilon. En general, sugiero utilizar la segunda variante.

Ambas variantes pueden usar un índice en startTime que será importante cuando la tabla crezca.

SG_
fuente
9
La versión de David no es buena, no puede usar índices. Para utilizar un índice, lo que tiene que filtro en la columna directamente, no en el resultado de una función ( date(), year(), datediff()o cualquiera similar)
Marki555
Estaba buscando cómo mysql convierte la fecha en fecha y hora, gracias por borrarlo agrega 00:00:00. ahora mis resultados tienen sentido
Contador م
1
Esta es la solución rápida correcta en comparación con otras respuestas que no pueden usar el índice si está disponible
Zamrony P. Juhara
23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

O

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
Salil
fuente
25
Esta es una pregunta terrible. Evita esto a toda costa. Si hay un índice en startTime, esta consulta no puede usarlo, ya que está aplicando una función a la columna en lugar de usarla directamente. Eso significa que cualquier consulta como esta requerirá un escaneo completo de la tabla. En una tabla grande, esto significará una consulta extremadamente lenta.
steveayre
Estoy de acuerdo, su respuesta es incorrecta : David publicó la respuesta correcta a continuación.
mindplay.dk
1
Por favor, use la respuesta de David, porque es mucho más rápido. Este es válido, pero no bueno para la velocidad ...
xarlymg89
1
@ CarlosAlbertoMartínezGadea Esta versión es lenta porque tiene que formatear cada valor a cadena antes de la comparación ... La versión de David no lo necesita, pero aún no puede usar índices, por lo que no es óptima. Vea la respuesta de XL_ para una versión que puede usar index. Desafortunadamente, no hay mejor manera de hacerlo correctamente en mysql
Marki555
1
Bajé esta respuesta porque la consulta no puede usar un índice, mientras que la respuesta de @ XL_ sí.
pedromanoel
2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

esto para el formato de fecha y hora en mysql usando DATE_FORMAT(date,format).

RT
fuente
1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

ayuda, puede convertir los valores como DATEantes de comparar.

Sarath
fuente
0

Puede convertir el campo DATETIME en DATE como:

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

Esto es muy eficaz.

SGAmpere
fuente
1
No, tampoco es eficiente. esto no podrá usar el índice si startTimeestá indexado
Zamrony P. Juhara
-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

También puede usar operadores de comparación en fechas MySQL si desea encontrar algo antes o después. Esto se debe a que están escritos de tal manera (de mayor valor a menor con ceros a la izquierda) que una simple clasificación de cadena los clasificará correctamente.

Fletcher Moore
fuente