2012-09-17 51 views
7
+----------+--------------+-------------------------+ 
| ticketid | ticketpostid |   date   | 
+----------+--------------+-------------------------+ 
| 1387935 |  3147808 | 2012-09-17 13:33:01  | 
| 1387935 |  3147812 | 2012-09-17 13:33:41  | 
| 1387938 |  3147818 | 2012-09-17 13:35:01  | 
| 1387938 |  3148068 | 2012-09-17 13:37:01  | 
| 1387938 |  3148323 | 2012-09-17 14:47:01  | 
| 1387939 |  3147820 | 2012-09-17 13:36:01  | 
| 1387939 |  3147834 | 2012-09-17 13:36:25  | 
| 1387939 |  3147851 | 2012-09-17 13:41:01  | 
| 1387939 |  3147968 | 2012-09-17 13:59:06  | 
| 1387939 |  3147996 | 2012-09-17 14:03:01  | 

Esto es el resultado de una consulta que escribí. Hay dos y más de dos filas con el mismo ticketid. Necesito encontrar la diferencia de tiempo entre las primeras dos fechas en cada ticketidDiferencia entre fechas en dos filas consecutivas

Ej.

+----------+--------------+-------------------------+ 
| ticketid | ticketpostid |   date   | 
+----------+--------------+-------------------------+ 
| 1387935 |  3147808 | 2012-09-17 13:33:01  | 
| 1387935 |  3147812 | 2012-09-17 13:33:41  | 
| 1387938 |  3147818 | 2012-09-17 13:35:01  | 
| 1387938 |  3148068 | 2012-09-17 13:37:01  | 
| 1387939 |  3147820 | 2012-09-17 13:36:01  | 
| 1387939 |  3147834 | 2012-09-17 13:36:25  | 

Como resultado;

+----------+--------------+ 
| ticketid |time diff(sec)| 
+----------+--------------+ 
| 1387935 |  40  | 
| 1387938 |  120  | 
| 1387939 |  24  | 

¿Me puede decir cómo puedo hacer esto?

Gracias.

+1

Gracias por los datos y resultados esperados. Es genial si muestra esto en forma 'INSERT', por lo que es fácil de crear como muestra, pero esto funciona. Por cierto, ¿qué versión de PostgreSQL? –

Respuesta

13

Para PostgreSQL, creo que desea que el lag window function comparar las filas; será mucho más eficiente que un autoensamblaje y filtro. Esto no funcionará con MySQL, ya que todavía no parece ser compatible con las funciones estándar de la ventana SQL: 2003; vea abajo.

Para encontrar sólo los dos más baja se puede utilizar la función dense_rank ventana sobre el ticketid, a continuación, filtrar los resultados para devolver sólo las filas donde dense_rank() = 2, es decir fila con la segunda de-bajo marca de tiempo, donde lag() producirá la fila con la marca de tiempo más baja.

Consulte this SQLFiddle que muestra la muestra de DDL y la salida.

SELECT ticketid, extract(epoch from tdiff) FROM (
    SELECT 
     ticketid, 
     ticketdate - lag(ticketdate) OVER (PARTITION BY ticketid ORDER BY ticketdate) AS tdiff, 
     dense_rank() OVER (PARTITION BY ticketid ORDER BY ticketdate) AS rank 
    FROM Table1 
    ORDER BY ticketid) x 
WHERE rank = 2; 

He usado ticketdate como el nombre de la columna de la fecha porque date es un nombre terrible para una columna (que es un nombre de tipo de datos) y nunca se debe utilizar; tiene que ser doblemente cotizado en muchas situaciones para funcionar.

El enfoque portátil es probablemente la unión automática que otros publicaron. El enfoque de función de ventana anterior probablemente también funciona en Oracle, pero no parece en MySQL. Por lo que yo sé, no es compatible con las funciones de la ventana SQL: 2003.

La definición del esquema funcionará con MySQL si SET sql_mode = 'ANSI' y usa timestamp en lugar de timestamp with time zone. Parece que las funciones de ventana no; MySQL se ahoga en la cláusula OVER. Ver this SQLFiddle.

1
select 
    ticketid 
    ,time_to_sec(timediff(t2.date, t1.date)) as timediff 
from table t1 
join table t2 on t1.ticketid=t2.ticketid and t1.ticketpostid<t2.ticketpostid 
+2

Creo que este enfoque es válido, sin embargo, devolverá filas adicionales cuando haya más de 2 de los mismos ticketids. Compararía ticket1 con ticket2, ticket2 con ticket3, pero también ticket1 con ticket3, lo cual no es deseable. –

+0

Es cierto, pero el sql se hace con respecto a los datos del problema. Se modifica fácilmente para tomar en consideración el 1º y 2º, o 1º y último o lo que sea. Está hecho para 2 :). –

1

Intentar esta consulta -

INSERT INTO ticket_post(ticketid, ticketpostid, date) VALUES 
(1387935, 3147808, '2012-09-17 13:33:01'), 
(1387935, 3147812, '2012-09-17 13:33:41'), 
(1387938, 3147818, '2012-09-17 13:35:01'), 
(1387938, 3148068, '2012-09-17 13:37:01'), 
(1387938, 3148323, '2012-09-17 14:47:01'), 
(1387939, 3147820, '2012-09-17 13:36:01'), 
(1387939, 3147834, '2012-09-17 13:36:25'), 
(1387939, 3147851, '2012-09-17 13:41:01'), 
(1387939, 3147968, '2012-09-17 13:59:06'), 
(1387939, 3147996, '2012-09-17 14:03:01'); 

SELECT 
    ticketid, 
    TIME_TO_SEC(TIMEDIFF((
    SELECT t.date FROM ticket_post t WHERE t.ticketid = t1.ticketid AND t.date > t1.date ORDER BY t.date LIMIT 1), 
    MIN(date) 
)) diff FROM ticket_post t1 
GROUP BY ticketid; 

+----------+------+ 
| ticketid | diff | 
+----------+------+ 
| 1387935 | 40 | 
| 1387938 | 120 | 
| 1387939 | 24 | 
+----------+------+ 
+0

Obtengo resultados diferentes y estoy un poco confundido. ¿Puedes mostrar tu esquema y los datos de muestra? Comparar: http://sqlfiddle.com/#!9/846e8/6 –

+0

Utilicé los datos de la pregunta. – Devart

+0

Ah. Hay dos conjuntos de datos de muestra allí. Usé el superior, tú usaste el otro. Eso lo explica. Mi error. Por cierto, vale la pena señalar en su respuesta que es solo MySQL. –

Cuestiones relacionadas