2012-02-08 165 views
6

La columna d es FECHA, la columna t es la hora, la columna v es, por ejemplo, INT. Supongamos que necesito todos los valores registrados después de las 15:00 del 1 de febrero de 2012 y en adelante. Si escribo¿Cómo combinar la fecha y la hora de diferentes columnas MySQL para compararlas con un DateTime completo?

SELECT * FROM `mytable` WHERE `d` > '2012-02-01' AND `t` > '15:00' 

todos los registros realizados antes de las 15:00 en cualquier fecha van a ser excluidos del conjunto de resultados (así como todos hechos en 2012-02-01) mientras que yo quiero verlos. Parece que sería fácil si hubiera una sola columna DATETIME, pero hay columnas separadas para fecha y hora en el caso de la mía.

Lo mejor que puedo ver ahora es algo así como

SELECT * FROM `mytable` WHERE `d` >= '2012-02-02' OR (`d` = '2012-02-01' AND `t` > '15:00') 

Cualquier una mejor idea? Tal vez hay una función para esto en MySQL? ¿No hay algo como

SELECT * FROM `mytable` WHERE DateTime(`d`, `t`) > '2012-02-01 15:00' 

posible?

Respuesta

14

Puede utilizar la función de MySQL CONCAT() añadir las dos columnas juntas en una sola, y luego compararlos así:

SELECT * FROM `mytable` WHERE CONCAT(`d`,' ',`t`) > '2012-02-01 15:00' 
+2

¿Está realmente destinado a funcionar bien con los tiempos de fecha (lo que significa que no hay pérdida de rendimiento significativo y ningún comportamiento inesperado)? – Ivan

+0

No estoy seguro ... puedes ejecutar 'explain' y ver cómo funciona. Por supuesto, usted siempre puede actualizar su tabla de forma masiva para usar una columna de fecha y hora en lugar de las dos separadas. –

+0

si realmente desea una fecha, puede usar esto en su lugar http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html # function_str-to-date –

1

Todo lo que tiene que hacer es convertirlo en marca de tiempo Unix y hacer selecciones apropiadas . Para esto debe usar las funciones de mysql como * unix_timestamp(). * Y * date_format *

Suponga que desea seleccionar las filas donde la marca de tiempo> 1328725800, la siguiente instrucción SQL haría la tarea.

select unix_timestamp(d)+3600*date_format(t,'%h)+60*date_format(t,'%i')+date_format(t,'%S') as timestamp from table where timestamp>1328725800 
+0

Por cierto, no funciona de esta manera. Un alias de columna ("timestamp" aquí) no se puede usar en la cláusula 'WHERE'; tenemos que usar' HAVING' en su lugar. Y no 'date_format (t, '% h)' pero 'date_format (t,'% H ')'. Pero gracias de todos modos, la consulta funciona unas 200 veces más rápido que la consulta que he utilizado como mi primer ejemplo. Sin embargo, la solución @ brian-glaz es aún más rápida. – Ivan

2

Aquí hay una versión limpia que no requiere operaciones de cadenas o la conversión a marcas de tiempo UTC en husos horarios.

DATE_ADD(date, INTERVAL time HOUR_SECOND) 
10

La función TIMESTAMP(expr1,expr2) es explícitamente para combinar los valores de fecha y hora:

Con un solo argumento, esta función devuelve la fecha o la fecha y hora expresión expr como un valor de fecha y hora. Con dos argumentos, agrega la expresión de tiempo expr2 a la expresión date o datetime expr1 y devuelve el resultado como un valor de fecha y hora.

Este uso resultante es justo lo que predijo:

SELECT * FROM `mytable` WHERE TIMESTAMP(`d`, `t`) > '2012-02-01 15:00' 
+0

Esto es genial, pero necesita convertir la parte después> con TIMESTAMP() también. – Maurice

0

En realidad, debería ser:

SELECT * FROM `mytable` WHERE CONCAT(`d`,' ',`t`) > '2012-02-01 15:00:00' 

Si usted quiere tomar segundos en cuenta, es necesario añadir los dos dígitos hasta el final;) ​​

Cuestiones relacionadas