¿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?

mysqllearner
fuente

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.

Priyank Bolia
fuente
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.

IvanRF
fuente
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')
Prusprus
fuente
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.

dotancohen
fuente
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 |
+----------------------+
Siraj Alam
fuente
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))
Michel van Engelen
fuente
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'
Raja Rama Mohan Thavalam
fuente
-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

imran
fuente