2012-06-21 13 views
8

Supponiamo che io ho due tabelle in questo modo:MySQL Join/confronto su una colonna DATETIME (<5.6.4 and > 5.6.4)

Events 
ID (PK int autoInc), Time (datetime), Caption (varchar) 

Position 
ID (PK int autoinc), Time (datetime), Easting (float), Northing (float) 

E 'sicuro, per esempio, elencare tutti gli eventi e la loro posizione se sono utilizzando il campo Time come criterio di adesione? Cioè .:

SELECT E.*,P.* FROM Events E JOIN Position P ON E.Time = P.Time 

O, anche semplicemente confrontando il valore datetime (tenendo conto che il valore parametrizzato può contenere il secondi frazionaria parte - che MySQL ha sempre accettato) esempio

SELECT E.* FROM Events E WHERE E.Time = @Time 

Capisco MySQL (prima della versione 5.6.4) memorizza solo campi datetime SENZA millisecondi. Quindi assumerei che questa query funzionerebbe correttamente. Tuttavia, dalla versione 5.6.4, ho letto che MySQL ora può memorizzare millisecondi con il campo datetime.

Supponendo valori datetime vengono inseriti tramite le funzioni come NOW(), i millisecondi vengono troncati (< 5.6.4) che Supporrei consentire query precedente per funzionare. Tuttavia, con la versione 5.6.4 e successive, questo potrebbe NON funzionare. Sono, e sarò interessato solo alla seconda accuratezza.

Se qualcuno potesse rispondere alle seguenti domande sarebbe molto apprezzato:

  1. In generale, come fa MySQL confrontare i campi datetime uno contro l'altro (si pensi query precedente).
  2. La query di cui sopra va bene e utilizza gli indici nei campi ? (MySQL 5.6.4)
  3. Esiste un modo per escludere i millisecondi? Cioè quando si inserisce e in join/select condizionali ecc.? (MySQL> 5.6.4)
  4. La query di partecipazione sopra funzionerà? (MySQL> 5.6.4)

EDIT

so di poter lanciare i datetimes, grazie per coloro che hanno risposto, ma sto cercando di affrontare la radice del problema qui (il fatto che il tipo di archiviazione/definizione è stata cambiata) e io NON voglio utilizzare le funzioni nelle mie query. Ciò nega tutto il mio lavoro di ottimizzazione delle query che applicano gli indici ecc., Per non parlare del dover riscrivere tutte le mie query.

EDIT2

qualcuno là fuori può suggerire un motivo per non unirsi su un campo DATETIME utilizzando secondo la precisione?

+0

bene per la terza domanda Usa questa data (time_column) questo farà il trucco –

+1

credo 'NOW()' in 5.6.4 o successiva non tiene in millisecondi a meno che non si passa in un parametro (0-6) che indica "* precisione frazionaria dei secondi *", quindi dovresti stare bene per l'unione finché non passi i parametri a 'NOW()' Altro [qui] (http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_now) –

+0

quale fuso orario viene utilizzato per DATETIME, dose che il fuso orario ha "salti", come http: // stackoverflow .com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result –

risposta

4

Sembra che gli sviluppatori di MySQL non ha voluto rompere la compatibilità a ritroso, in modo da utilizzare millisecondi, si deve esplicitamente di cambiare le tabelle, SQL, ecc per utilizzare questa funzione:

http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_now

NOW ([FSP])

partire da MySQL 5.6.4, se viene dato l'argomento FSP per specificare un precisione dei secondi frazionari da 0 a 6, il valore di ritorno include una parte dei secondi frazionari di . Prima di 5.6.4, qualsiasi argomento viene ignorato.

http://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html

MySQL 5.6.4 e fino espande supporto frazionaria secondi per TIME, DATETIME , e valori timestamp, fino a microsecondi (6 cifre) precisione:

Per definire una colonna che include una parte di secondi frazionari, utilizzare la sintassi type_name (fsp), dove type_name è TIME, DATETIME o TIMESTAMP e fsp è la precisione dei secondi frazionari. Per esempio:

CREATE TABLE t1 (t TIME(3), dt DATETIME(6)); The fsp value, if given, must be in the range 0 to 6. A value of 0 signifies that there is no fractional part. If omitted, the default precision is 0. (This differs from the standard SQL default of 6, for compatibility with previous MySQL versions.) 
+0

+1 grazie biziclop. Questa è una buona notizia, non dovrei cambiare nulla. – Simon

+0

Ho appena ampliato il commento di Zane Bien :) – biziclop

1

Prova questa query. Per le domande 3 e 4 questo funzionerà correttamente.Ancora non è una buona pratica da utilizzare campo di tempo per unisce

SELECT E.*,P.* FROM Events E JOIN Position P ON date(E.Time) = date(P.Time) 

Anche se vi ho dato una soluzione, ma si sarà limitato a inserire lo stesso tempo in tabelle differenti. Quindi sarai in grado di confrontare ma è abbastanza difficile perché allo stesso tempo non puoi eseguire due query di inserimento. Quindi dovrai fare un po 'di menuall per questo. Se vuoi leggere di più leggi questo articolo.

http://billauer.co.il/blog/2009/03/mysql-datetime-epoch-unix-time/

+0

Potresti spiegare PERCHE 'non è una buona pratica usare il campo del tempo per un join. Grazie – Simon

+0

ho visto questo post del blog, e mentre invita la discussione sull'uso di 'DATETIME' o' INT' come memoria temporale, non risolve i problemi di accuratezza quando si confrontano i valori di 'DATETIME'. Usando un 'JOIN' o un confronto di uguaglianza semplice. – Simon

+0

Un semplice esempio in cui la registrazione su una colonna 'DATETIME' potrebbe non riuscire: poiché entrambi gli inserimenti non possono essere eseguiti contemporaneamente, potrebbe esserci un (piccolo) ritardo tra di essi. Supponiamo che il primo inserto sia 19: 59: 59.999 (nota i millisecondi), che può essere troncato alle 19:59:59, e il secondo inserto è solo 1 ms più tardi alle 20: 00: 00.000, che termina alle 20:00 : 00. Ora buona fortuna con il tuo join. Questo è sotto il presupposto che tu stia effettivamente usando 'NOW()' nelle tue query di inserimento, non un valore temporale precalcolato uguale per entrambe le query. – Bart

Problemi correlati