2012-09-17 18 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  | 

Questo è il risultato di una query che ho scritto. Ci sono due e più di due righe con lo stesso ticketid. Devo trovare la differenza di orario tra le prime due date in ogni ticketidDifferenza tra le date in due file consecutive

Es.

+----------+--------------+-------------------------+ 
| 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  | 

Di conseguenza;

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

Puoi dirmi come posso farlo?

Grazie.

+1

Grazie per i dati e risultati attesi. È fantastico se lo mostri in forma "INSERT", quindi è facile da creare come esempio, ma funziona. BTW, quale versione di PostgreSQL? –

risposta

13

per PostgreSQL, penso che si desidera che il lag window function per confrontare le righe; sarà molto più efficiente di un self-join e filtro. Questo non funzionerà con MySQL, dal momento che non sembra supportare le funzioni standard della finestra SQL: 2003; vedi sotto.

Per trovare solo i due più basso è possibile utilizzare la funzione di dense_rank finestra sopra il ticketid, poi filtrare i risultati per restituire solo le righe in cui dense_rank() = 2, cioè fila con il secondo-da-basso timestamp, dove lag() produrrà la riga con il timestamp più basso.

Vedere this SQLFiddle che mostra il campione DDL e l'output.

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; 

Ho usato ticketdate come nome per la colonna della data perché date è un nome terribile per una colonna (è un nome del tipo di dati) e non dovrebbe mai essere utilizzato; deve essere citato due volte in molte situazioni per funzionare.

L'approccio portatile è probabilmente l'autoaggiunta che altri hanno pubblicato. L'approccio alla funzione della finestra sopra probabilmente funziona anche su Oracle, ma non sembra in MySQL. Per quanto posso scoprire che non supporta le funzioni della finestra SQL: 2003.

La definizione dello schema funzionerà con MySQL se si utilizza SET sql_mode = 'ANSI' e si utilizza timestamp anziché timestamp with time zone. Sembra che le funzioni della finestra non lo faranno; MySQL soffoca sulla clausola OVER. Vedi 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

Penso che questo approccio sia valido, tuttavia, restituirà righe aggiuntive quando ci sono più di 2 degli stessi ticketid. Comparerebbe ticket1 a ticket2, ticket2 a ticket3, ma anche ticket1 a ticket3, che non è desiderato. –

+0

Vero, ma la sql viene eseguita per quanto riguarda i dati del problema. È facilmente modificabile per prendere in considerazione 1a e 2a, o 1a e ultima o qualsiasi altra cosa. È fatto per 2 :). –

1

Prova questa ricerca -

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

Ottengo risultati diversi e sono un po 'confuso. Puoi mostrare il tuo schema e dati di esempio? Confronta: http://sqlfiddle.com/#!9/846e8/6 –

+0

Ho usato i dati dalla domanda. – Devart

+0

Ah. Ci sono due set di dati di esempio. Ho usato quello superiore, tu hai usato l'altro. Questo lo spiega. Errore mio. A proposito, vale la pena notare nella tua risposta che è solo MySQL. –