2011-10-28 7 views
7

Devo confrontare i risultati relativi allo stesso tempo tra due tabelle, ma i timestamp differiscono di qualche secondo a causa di come sono stati registrati. Vorrei ottenere un risultato come in Esempio 1 ma ottengo solo i valori con l'asterisco, come in Esempio 2. Qual è il modo migliore per rimuovere i secod dal confronto o per selezionare il valore corrispondente al valore DATETIME più vicino?MySQL seleziona DATETIME simile al minuto

Attualmente sto usando questa query:

SELECT Table1.TimeSTamp1, Table1.Param1, Table2.TimeStamp2, Table2.Param2 
    FROM Table1, Table2 
    WHERE ... conditions for the other parameters of Table1 and Table2... 
    AND Table1.TimeSTamp1 = Table2.TimeStamp2 

Ogni suggerimento sulle migliori prassi è accolto con grande favore.


Esempio 1

TimeStamp1   ¦ Param1 ¦ TimeStamp2   ¦ Param2 
2011-01-01 00:00:35 ¦ 1  ¦ 2011-01-01 00:00:35 ¦ a  * 
2011-01-01 00:01:35 ¦ 2  ¦ 2011-01-01 00:01:35 ¦ b 
2011-01-01 00:02:37 ¦ 3  ¦ 2011-01-01 00:02:35 ¦ c 
2011-01-01 00:03:31 ¦ 4  ¦ 2011-01-01 00:03:35 ¦ d 
2011-01-01 00:04:32 ¦ 5  ¦ 2011-01-01 00:04:35 ¦ e 
2011-01-01 00:05:38 ¦ 6  ¦ 2011-01-01 00:05:35 ¦ f 
2011-01-01 00:06:36 ¦ 7  ¦ 2011-01-01 00:06:36 ¦ g  * 
2011-01-01 00:07:32 ¦ 8  ¦ 2011-01-01 00:07:35 ¦ h 
2011-01-01 00:08:33 ¦ 9  ¦ 2011-01-01 00:08:35 ¦ i 
2011-01-01 00:09:33 ¦ 10  ¦ 2011-01-01 00:09:33 ¦ l  * 
2011-01-01 00:10:35 ¦ 11  ¦ 2011-01-01 00:10:35 ¦ m  * 
2011-01-01 00:11:29 ¦ 12  ¦ 2011-01-01 00:11:31 ¦ n 

lll Esempio 2

TimeStamp1   ¦ Param1 ¦ TimeStamp2   ¦ Param2 
2011-01-01 00:00:35 ¦ 1  ¦ 2011-01-01 00:00:35 ¦ a 
2011-01-01 00:06:36 ¦ 7  ¦ 2011-01-01 00:06:36 ¦ g 
2011-01-01 00:09:33 ¦ 10  ¦ 2011-01-01 00:09:33 ¦ l 
2011-01-01 00:10:35 ¦ 11  ¦ 2011-01-01 00:10:35 ¦ m 

risposta

10

Questa espressione MySql vi restituirà valori datetime con i secondi azzerati.

Dai un'occhiata a questo. http://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format. Quindi potresti finire con una query come questa:

SELECT Table1.TimeSTamp1, Table1.Param1, Table2.TimeStamp2, Table2.Param2 
    FROM Table1 
    JOIN Table2 ON CONVERT(DATE_FORMAT(Table1.TimeStamp1,'%Y-%m-%d-%H:%i:00'),DATETIME) 
       = CONVERT(DATE_FORMAT(Table2.TimeStamp2,'%Y-%m-%d-%H:%i:00'),DATETIME) 
    WHERE ... conditions for the other parameters of Table1 and Table2... 

Ma attenzione. I timestamp generati automaticamente sono un po 'come i numeri in virgola mobile; quando due di loro si presentano uguali tra loro, è solo fortuna. Troncare i tuoi timestamp al minuto può essere OK, ma potrebbe anche essere meglio sottrarre un timestamp da un altro e confrontare le differenze (oi valori assoluti delle differenze).

Inoltre, questo join sarà lento perché deve eseguire la funzione di secondo-troncamento su ogni valore, quindi non può utilizzare alcun indice.

È possibile sottrarre un timestamp da un altro con TIMESTAMPDIFF(). Ma fa attenzione. Questa funzione funziona correttamente solo al livello dei secondi per i timestamp in pochi giorni l'uno dall'altro; trabocca senza grazia (come ho scoperto con grande dolore).

Si potrebbe provare a troncare i timestamp a minuti al momento in cui li si inserisce. Questo ti permetterebbe di indicizzarli.

+0

Grazie, TIMESTAMPDIFF rende il lavoro. a volte ottengo voci doppie e rimuoverle richiede molto tempo.Verificherò se la conversione della data è più veloce in questo caso. –

1
WHERE ... 
AND ABS(UNIX_TIMESTAMP(TimeStamp1) - UNIX_TIMESTAMP(TimeStamp2)) < :threshold: 

dove threshold è il numero di secondi dopo i quali si desidera non è più una partita (per esempio 60 per 1 minuto).

+0

L'ho provato ma ci vuole troppo tempo, fino all'errore 2013 –

1

Si potrebbe utilizzare TIMESTAMPDIFF per calcolare la differenza di datetimes in secondi:

SELECT t1.TimeStamp1, t1.Param1, t2.TimeStamp2, t2.Param2 
FROM Table1 t1 
LEFT JOIN Table2 t2 
ON ABS(TIMESTAMPDIFF(SECOND,t1.TimeStamp1,t2.TimeStamp2))<=4 
WHERE ... 

Notando Ollie Jones warning, ho testato TIMESTAMPDIFF su MySQL versione 5.1.58 e non ha trovato troppo pieno con timestamp differenti fino ad almeno 10000 anni. Quindi forse questo problema è stato risolto.