¿Cómo seleccionar la fecha de la columna datetime?


238

Tengo una columna de tipo "datetime" con valores como 2009-10-20 10:00:00

Me gustaría extraer la fecha de datetime y escribir una consulta como:

SELECT * FROM 
data 
WHERE datetime = '2009-10-20' 
ORDER BY datetime DESC

¿Es la siguiente la mejor manera de hacerlo?

SELECT * FROM 
data 
WHERE datetime BETWEEN('2009-10-20 00:00:00' AND '2009-10-20 23:59:59')
ORDER BY datetime DESC

Sin embargo, esto devuelve un conjunto de resultados vacío. ¿Alguna sugerencia?

Respuestas:


456

Puedes usar la DATE()función de MySQL :

WHERE DATE(datetime) = '2009-10-20'

También puedes probar esto:

WHERE datetime LIKE '2009-10-20%'

Consulte esta respuesta para obtener información sobre las implicaciones de rendimiento del uso LIKE.


2
probé este: Donde DATE (datetime) = '2009-10-20', funciona
mysqllearner

44
El primero es muy lento e ignora los índices. Es mejor tener LIKE 'date%'
kachar

DONDE FECHA (fecha y hora) COMO '% keyword%' funciona, gracias
silvia zulinka

2
Creo que esto no funciona como se esperaba si la zona horaria de Rails no es UTC. Esto se debe a que DATE () resuelve el valor de la columna en UTC. Por lo tanto, no se encontrará una fecha como "Vie, 30 de diciembre de 2016 00:00:00 SGT +08: 00" que esperamos encontrar si consultamos "2016-12-30". ¿Por qué? Porque DATE () lo resolverá a su equivalente UTC antes de hacer el comparativo, que es "2016-12-29 16:00:00 UTC". Corrígeme si me equivoco, ya que esto también fue un problema para mí hasta hace poco.
Tikiboy

WHERE DATE (datetime) = '{? Sdate} funciona perfectamente para un parámetro de Crystal Reports! ¡Buen trabajo!
MikeMighty

94

El uso WHERE DATE(datetime) = '2009-10-20' tiene problemas de rendimiento . Como se indica aquí :

  • calculará DATE()para todas las filas, incluidas las que no coinciden.
  • hará que sea imposible usar un índice para la consulta.

Utilizar BETWEENo >, <, =los operadores que permiten utilizar un índice:

SELECT * FROM data 
WHERE datetime BETWEEN '2009-10-20 00:00:00' AND '2009-10-20 23:59:59'

Actualización: el impacto en el uso en LIKElugar de operadores en una columna indexada es alto . Estos son algunos resultados de pruebas en una tabla con 1,176,000 filas:

  • utilizando datetime LIKE '2009-10-20%'=> 2931 ms
  • usando datetime >= '2009-10-20 00:00:00' AND datetime <= '2009-10-20 23:59:59'=> 168ms

Al hacer una segunda llamada sobre la misma consulta, la diferencia es aún mayor: 2984 ms frente a 7 ms (¡sí, solo 7 milisegundos!). Encontré esto mientras reescribía un código antiguo en un proyecto usando Hibernate.


Interesante, si la implementación DATE(datetime)de BETWEEN AND MySql se convierte automáticamente en detrás de las escenas, obtenemos una breve declaración y un excelente rendimiento. Por qué no? ¿Por qué no hicieron esto? :)
Cherry

Porque algo así DATE(datetime) in (:list)no funcionaBETWEEN
Tim

25

Puede formatear la fecha y hora en la porción YMD:

DATE_FORMAT(datetime, '%Y-%m-%d')

2
Y de esta manera solo puede obtener la parte del tiempo si es necesario:DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel

esto funciona muy bien formateando la fecha y hora, pero a cambio, la base de datos devolverá una nueva matriz para establecer el nombre para ella solo con el nombre deseado al final DATE_FORMAT (columnName, '% Y-% m-% d') arrayName para obtener más detalles, verifique documentations dev.mysql.com/doc/refman/8.0/en/…
Ridha Rezzag

15

Aunque todas las respuestas en la página devolverán el resultado deseado, todas tienen problemas de rendimiento. Nunca realice cálculos en los campos de la WHEREcláusula (incluido un DATE()cálculo) ya que ese cálculo debe realizarse en todas las filas de la tabla.

El BETWEEN ... ANDconstructo es inclusivo para ambas condiciones fronterizas, lo que requiere que se especifique la sintaxis 23:59:59 en la fecha de finalización, que en sí tiene otros problemas (transacciones de microsegundos, que creo que MySQL no admitió en 2009 cuando se hizo la pregunta).

La forma correcta de consultar un timestampcampo MySQL para un día en particular es verificar si es mayor que igual a la fecha deseada y menor que el día posterior, sin hora especificada.

WHERE datetime>='2009-10-20' AND datetime<'2009-10-21'

Este es el método de más rápido rendimiento, menor memoria y menor uso de recursos, y además admite todas las características de MySQL y los casos de esquina, como la precisión de la marca de tiempo de menos de un segundo. Además, es una prueba de futuro.


1
Y, utilizando su argumento de rendimiento, ¿están "> =" y "<" igualmente calculados en cada fila de la tabla, o el servidor SQL simplemente "mágicamente" sabe si un número es mayor que otro? :-)
Javier Guerrero

@JavierGuerrero: Mi ejemplo compara dos constantes: una de la tabla y un literal de cadena.
dotancohen

El "uno de la tabla" no es una constante, varía para cada fila, por lo que debe hacerse el mismo cálculo para cada fila (y también, ambos deben convertirse al tiempo de época para realizar la comparación)
Javier Guerrero

9

Aquí están todos los formatos

Digamos que esta es la columna que contiene el datetimevalor, tabla data.

+--------------------+
| date_created       |
+--------------------+
| 2018-06-02 15:50:30|
+--------------------+

mysql> select DATE(date_created) from data;
+--------------------+
| DATE(date_created) |
+--------------------+
| 2018-06-02         |
+--------------------+

mysql> select YEAR(date_created) from data;
+--------------------+
| YEAR(date_created) |
+--------------------+
|               2018 |
+--------------------+

mysql> select MONTH(date_created) from data;
+---------------------+
| MONTH(date_created) |
+---------------------+
|                   6 |
+---------------------+

mysql> select DAY(date_created) from data;
+-------------------+
| DAY(date_created) |
+-------------------+
|                 2 |
+-------------------+

mysql> select HOUR(date_created) from data;
+--------------------+
| HOUR(date_created) |
+--------------------+
|                 15 |
+--------------------+

mysql> select MINUTE(date_created) from data;
+----------------------+
| MINUTE(date_created) |
+----------------------+
|                   50 |
+----------------------+

mysql> select SECOND(date_created) from data;
+----------------------+
| SECOND(date_created) |
+----------------------+
|                   31 |
+----------------------+

5

Puedes usar:

DATEDIFF ( day , startdate , enddate ) = 0

O:

DATEPART( day, startdate ) = DATEPART(day, enddate)
AND 
DATEPART( month, startdate ) = DATEPART(month, enddate)
AND
DATEPART( year, startdate ) = DATEPART(year, enddate)

O:

CONVERT(DATETIME,CONVERT(VARCHAR(12), startdate, 105)) = CONVERT(DATETIME,CONVERT(VARCHAR(12), enddate, 105))

5

manera simple y mejor de usar la función de fecha

ejemplo

SELECT * FROM 
data 
WHERE date(datetime) = '2009-10-20' 

O

SELECT * FROM 
data 
WHERE date(datetime ) >=   '2009-10-20'  && date(datetime )  <= '2009-10-20'

-5

Bueno, usar LIKEen la declaración es la mejor opción WHERE datetime LIKE '2009-10-20%' que debería funcionar en este caso

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.