Come selezionare la data dalla colonna datetime?


238

Ho una colonna di tipo "datetime" con valori come 2009-10-20 10:00:00

Vorrei estrarre la data da datetime e scrivere una query come:

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

Il seguente è il modo migliore per farlo?

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

Questo tuttavia restituisce un gruppo di risultati vuoto. Eventuali suggerimenti?

Risposte:


456

Puoi usare la DATE()funzione di MySQL :

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

Puoi anche provare questo:

WHERE datetime LIKE '2009-10-20%'

Vedi questa risposta per informazioni sulle implicazioni prestazionali dell'utilizzo LIKE.


2
provato questo: Where DATE (datetime) = '2009-10-20', funziona
mysqllearner

44
Il primo è molto lento e ignora gli indici. È meglio avere LIKE 'date%'
kachar

DOVE DATA (datetime) COME "% keyword%" funziona, grazie
silvia zulinka,

2
Credo che questo non funzioni come previsto se il fuso orario di Rails è diverso da UTC. Questo perché DATE () risolve il valore della colonna in UTC. Pertanto, una data come "Ven, 30 dic 2016 00:00:00 SGT +08: 00" che ci aspettiamo di trovare se abbiamo richiesto "30-12-2016" non verrà trovata. Perché? Perché DATE () lo risolverà nel suo equivalente UTC prima di fare il confronto, che è "29-12-2016 16:00:00 UTC". Correggimi se sbaglio perché anche questo è stato un problema per me fino a poco tempo fa.
Tikiboy,

WHERE DATE (datetime) = '{? Sdate} funziona perfettamente per un parametro Crystal Reports! Bel lavoro!
MikeMighty,

94

L'utilizzo WHERE DATE(datetime) = '2009-10-20' ha problemi di prestazioni . Come indicato qui :

  • calcolerà DATE()per tutte le righe, comprese quelle che non corrispondono.
  • renderà impossibile usare un indice per la query.

Utilizzare BETWEENo >, <, =gli operatori che permettono di utilizzare un indice:

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

Aggiornamento: l' impatto sull'uso LIKEinvece degli operatori in una colonna indicizzata è elevato . Questi sono alcuni risultati dei test su una tabella con 1.176.000 righe:

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

Quando si effettua una seconda chiamata sulla stessa query, la differenza è ancora maggiore: 2984ms contro 7ms (sì, solo 7 millisecondi!). Ho trovato questo mentre riscrivevo un vecchio codice su un progetto usando Hibernate.


Interessante, se l'implementazione di MySql si converte automaticamente DATE(datetime)in BETWEEN AND scene, otteniamo una breve affermazione e ottime prestazioni. Perchè no? Perché non l'hanno fatto? :)
Cherry,

Perché qualcosa di simile non DATE(datetime) in (:list)funziona conBETWEEN
Tim

25

È possibile formattare il datetime nella parte YMD:

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

2
E in questo modo puoi ottenere solo la parte del tempo se necessario:DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel,

funziona alla grande formando il datetime ma in cambio il database restituirà un nuovo array per impostare il nome per esso solo annuncio il nome desiderato alla fine DATE_FORMAT (nome colonna, '% Y-% m-% d') arrayName per ulteriori dettagli controllare documentazioni dev.mysql.com/doc/refman/8.0/it/…
Ridha Rezzag,

15

Sebbene tutte le risposte sulla pagina restituiranno il risultato desiderato, tutte hanno problemi di prestazioni. Non eseguire mai calcoli sui campi nella WHEREclausola (incluso un DATE()calcolo) poiché tale calcolo deve essere eseguito su tutte le righe della tabella.

Il BETWEEN ... ANDcostrutto è inclusivo per entrambe le condizioni al confine, che richiede di specificare la sintassi 23:59:59 alla data di fine che presenta altri problemi (transazioni in microsecondi, che credo che MySQL non supportasse nel 2009 quando è stata posta la domanda).

Il modo corretto di eseguire una query su un timestampcampo MySQL per un determinato giorno è verificare la presenza di valori superiori a uguali rispetto alla data desiderata e inferiori a rispetto al giorno successivo, senza specificare l'ora.

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

Questo è il metodo con le prestazioni più rapide, la memoria più bassa e le risorse meno dispendiose e supporta inoltre tutte le funzionalità di MySQL e casi angolari come la precisione del timestamp al secondo. Inoltre, è a prova di futuro.


1
E, usando l'argomento delle prestazioni, "> =" e "<" sono calcolati equamente su ogni riga della tabella, oppure il server SQL solo "magicamente" sa se un numero è maggiore di altri? :-)
Javier Guerrero,

@JavierGuerrero: il mio esempio confronta due costanti: una dalla tabella e una stringa letterale.
dotancohen,

"Quello dalla tabella" non è una costante, varia per ogni riga, quindi lo stesso calcolo deve essere fatto per ogni riga (e inoltre, entrambi devono essere convertiti in tempo per eseguire il confronto)
Javier Guerrero

9

Ecco tutti i formati

Supponiamo che questa sia la colonna che contiene il datetimevalore, tabella 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

Puoi usare:

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

modo semplice e migliore per utilizzare la funzione data

esempio

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

Bene, usare LIKEin statement è l'opzione migliore WHERE datetime LIKE '2009-10-20%' che dovrebbe funzionare in questo caso

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.