2012-06-21 7 views
8

Supongamos que tengo dos tablas de este modo:MySQL Join/Comparación en una columna 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) 

¿Es seguro, por ejemplo, una lista de todos los eventos y su posición si soy usando el campo Time como mis criterios de unión? Es decir .:

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

OR, incluso simplemente comparar un valor de fecha y hora (teniendo en cuenta que el valor parametrizado puede contener la parte fraccional segundo - que MySQL siempre ha aceptado), por ejemplo,

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

entiendo MySQL (antes de la versión 5.6.4) sólo almacena los campos de fecha y hora SIN milisegundos. Así que supongo que esta consulta funcionaría bien. Sin embargo, a partir de la versión 5.6.4, he leído que MySQL ahora puede almacenar milisegundos con el campo de fecha y hora.

Suponiendo que los valores de fecha y hora se inserten mediante funciones como NOW(), los milisegundos se truncan (< 5.6.4) lo que supondría permitir que la consulta anterior funcione. Sin embargo, con la versión 5.6.4 y posterior, esto podría NO funcionar. Estoy, y solo estaré interesado en la segunda precisión.

Si alguien puede responder a las siguientes preguntas sería muy apreciada:

  1. En general, ¿cómo se compara MySQL campos de fecha y hora uno contra el otro (considere la consulta anterior).
  2. ¿Es correcta la consulta anterior y utiliza índices en los campos de tiempo ? (MySQL < 5.6.4)
  3. ¿Hay alguna forma de excluir milisegundos? Es decir. al insertar y en condicional une/selecciona etc.? (MySQL> 5.6.4)
  4. ¿Funcionará la consulta de unión anterior? (MySQL> 5.6.4)

EDITAR

Sé que puedo emitir los datetimes, gracias por los que respondieron, pero estoy tratando de hacer frente a la raíz de la problema aquí (el hecho de que el tipo de almacenamiento/definición ha sido cambiado) y NO QUIERO usar funciones en mis consultas. Esto niega todo mi trabajo de optimización de consultas aplicando índices, etc., sin mencionar tener que reescribir todas mis consultas.

Edit2

¿Puede alguien por ahí sugerir una razón para no unirse en un campo DATETIME usando segunda exactitud?

+0

bien para su tercera cuestión, el uso de esta fecha (time_column) esto va a hacer el truco –

+1

Creo 'NOW()' en 5.6.4 o posterior no será factor en milisegundos a menos que pase en un parámetro (0-6) que indica la "* precisión de segundos fraccionarios *", por lo que debe estar bien para la unión, siempre y cuando no pase los parámetros a 'AHORA()' Más [aquí] (http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_now) –

+0

qué zona horaria se usa para DATETIME, dosis que la zona horaria tiene "saltos", como http: // stackoverflow .com/questions/6841333/why-is-restar-these-two-times-in-1927-giving-a-strange-result –

Respuesta

4

Parece que los desarrolladores de MySQL no querían romper la compatibilidad hacia atrás, por lo que utilizar milisegundos, que explícitamente tiene que cambiar su tablas, SQL, etc., para utilizar esta función:

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

NOW ([FSP])

a partir de MySQL 5.6.4, si se da el argumento FSP para especificar un segundos fraccionales de precisión de 0 a 6, el valor de retorno incluye una parte de segundos fraccionarios de esos muchos dígitos. Antes de 5.6.4, se ignora cualquier argumento .

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

MySQL 5.6.4 y hasta expande apoyo fraccional segundo por el tiempo, DATETIME, y los valores de fecha y hora, con hasta microsegundos (6 dígitos) de precisión:

Para definir una columna que incluye una parte de segundos fraccionarios, use la sintaxis type_name (fsp), donde type_name es TIME, DATETIME o TIMESTAMP, y fsp es la precisión de segundos fraccionarios. Por ejemplo:

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 gracias biziclop. Esas son buenas noticias, no debería tener que cambiar nada. – Simon

+0

Acabo de expandir el comentario de Zane Bien :) – biziclop

1

Pruebe esta consulta. Para las preguntas 3 y 4, esto funcionará bien.Aún así, no es una buena práctica utilizar campo de hora para las uniones

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

Aunque os he dado una solución, sino que se limitará a insertar el mismo tiempo en diferentes tablas. Entonces podrá comparar pero es bastante difícil porque al mismo tiempo no puede ejecutar dos consultas insertadas. Entonces tendrás que hacer un trabajo mental para esto. Si quieres leer más, lee este artículo.

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

+0

Podría explicar por qué no es una buena práctica usar el campo de tiempo para una unión. Gracias, – Simon

+0

, he visto esta publicación de blog, y si bien invita a debatir sobre el uso de 'DATETIME' o' INT' como almacenamiento de tiempo, realmente no aborda los problemas de precisión cuando se comparan los valores de 'DATETIME'. Usando una 'JOIN' o simple comparación de igualdad. – Simon

+0

Ejemplo simple donde la unión en una columna 'DATETIME' puede fallar: dado que ambas inserciones no pueden suceder al mismo tiempo, puede haber un retraso (pequeño) entre ellas. Supongamos que el primer inserto está a las 19: 59: 59.999 (nótese los milisegundos), que puede truncarse a 19:59:59, y el segundo inserto es solo 1 ms más tarde a las 20: 00: 00.000, que se trunca a las 20:00 : 00. Ahora buena suerte con tu unión. Esto es bajo la suposición de que de hecho estás usando 'NOW()' en tus consultas de inserción, no un valor de tiempo precalculado igual para ambas consultas. – Bart

Cuestiones relacionadas