MySQL SELECT DOVE il datetime corrisponde al giorno (e non necessariamente all'ora)


127

Ho una tabella che contiene una colonna datetime. Desidero restituire tutti i record di un determinato giorno indipendentemente dall'ora. O in altre parole, se la mia tabella contenesse solo i seguenti 4 record, solo il 2 ° e il 3 ° sarebbero restituiti se limitassi al 25-12-2012.

2012-12-24 00:00:00
2012-12-25 00:00:00
2012-12-25 06:00:00
2012-12-26 05:00:00

Si veda la risposta di John Woo a stackoverflow.com/questions/14769026/...
ekerner

Risposte:


326

MAI MAI usare un selettore come DATE(datecolumns) = '2012-12-24'- è un killer delle prestazioni:

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

È molto più veloce da usare

SELECT * FROM tablename 
WHERE columname BETWEEN '2012-12-25 00:00:00' AND '2012-12-25 23:59:59'

poiché ciò consentirà l'utilizzo dell'indice senza calcolo.

MODIFICARE

Come sottolineato da Used_By_Al già, nel tempo trascorso dalla risposta iniziale nel 2012, sono emerse versioni di MySQL, dove l'uso di "23: 59: 59" come fine del giorno non è più sicuro. Una versione aggiornata dovrebbe leggere

SELECT * FROM tablename 
WHERE columname >='2012-12-25 00:00:00'
AND columname <'2012-12-26 00:00:00'

L'essenza della risposta, ovvero l'evitamento di un selettore su un'espressione calcolata, ovviamente rimane valida.


Stavo per commentare che la soluzione di a1ex07 non sembra buona come le altre. Dopo aver letto il tuo post, forse ho bisogno di invertire il mio pensiero!
user1032531

2
Appena testato su due server, quanto sopra è MOLTO (almeno 10 volte) più veloce di date () = '' specialmente per tabelle enormi. Grazie
zzapper il

1
@KonradViltersten Ho usato un modo molto dettagliato per pronunciare la query per renderla più leggibile e portare a casa il mio punto, perfezionandolo. La risposta di a1ex07 ha la sintassi sparsa.
Eugen Rieck,

9
@KonradViltersten - Meglio ancora: WHERE col >= '2012-12-25' AND col < '2012-12-25' + INTERVAL 1 DAY. Evita 0 tempo e lavora per DATE, DATETIME, DATETIME(6), ecc e si occupa di salto-day, ecc
Rick James

1
'2012-12-25 23:59:59' NON È VALIDO alla fine della giornata, è sempre stata una cattiva idea e causerà bug per le versioni di MySQL che supportano la precisione sub-second time. Molto meglio usare l'approccio di Rick James (sopra) o a1ex07 (altra risposta)
Used_By_Al già

34

... WHERE date_column >='2012-12-25' AND date_column <'2012-12-26'potrebbe potenzialmente funzionare meglio (se hai un indice su date_column) di DATE.


1
In realtà mi chiedo cosa sia più veloce - questa o la BETWEENsoluzione ... qualcuno è stato contrassegnato?
jave.web,

6
Non dovrebbe fare alcuna differenza. BETWEENè solo un modo di scrivere field >= value1 and fied<= value2.
a1ex07,

1
Si noti che nel Manuale MySQL: "Per risultati ottimali quando si utilizza BETWEEN con valori di data o ora, utilizzare CAST () per convertire esplicitamente i valori nel tipo di dati desiderato. Esempi: se si confronta un DATETIME con due valori DATE, convertire la DATA valori su valori DATETIME. Se si utilizza una costante di stringa come "2001-1-1" in un confronto a una DATA, eseguire il cast della stringa a una DATA. " Quindi, a meno che non siano tutti dello stesso tipo, è meglio lanciarli esplicitamente.
techdude,

21

Puoi usare %:

SELECT * FROM datetable WHERE datecol LIKE '2012-12-25%'

13
LIKE sembra essere lento come DATE (datetimecol). Meglio usare la soluzione di Eugen o a1ex07.
Marie Fischer,

3
Non si tratta sempre di velocità. Quindi mi piace questa soluzione. È molto più leggibile.
Simon Hansen,
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.