2016-05-10 18 views
0

Ich habe eine Reihe von Daten, die eine type Spalte und eine created_at Zeitspalte hat. Ich habe bereits eine Abfrage, die die relevanten Daten aus der Datenbank zieht, und das sind die Daten, die zurückgegeben werden. Was ich tun möchte, ist irgendwie aggregieren diese Daten so einen zeitlichen Abstand zwischen jedem Fall erhalten, so dass die AusgangsdatenAggregation mehrerer Zeilen mehr als einmal

type   | created_at     | row_num 
----------------------------------------------------- 
"ordersPage" | "2015-07-21 11:32:40.568+12" | 1 
"getQuote"  | "2015-07-21 15:49:47.072+12" | 2 
"completeBrief" | "2015-07-23 01:00:15.341+12" | 3 
"sendBrief"  | "2015-07-24 08:59:42.41+12" | 4 
"sendQuote"  | "2015-07-24 18:43:15.967+12" | 5 
"acceptQuote" | "2015-08-03 04:40:20.573+12" | 6 

Die Zeilennummer wird aus der Standardzeilennummer Funktion in Postgres

ROW_NUMBER() OVER (ORDER BY created_at ASC) AS row_num 

zurück aussehen könnte so etwas wie diese

type_1   | type_2   | time_distance 
-------------------------------------------------------- 
"ordersPage" | "getQuote"  | 123423.3423 
"getQuote"  | "completeBrief" | 123423.3423 
"completeBrief" | "sendBrief"  | 123423.3423 
"sendBrief"  | "sendQuote"  | 123423.3423 
"sendQuote"  | "acceptQuote" | 123423.3423 

Der zeitliche Abstand wäre ein Schwimmer in Millisekunden sein, in anderen Abfragen ich habe so etwas wie dies mit Zeitdifferenzen erhalten .

EXTRACT(EPOCH FROM (MAX(events.created_at) - MIN(events.created_at))) 

Aber dieses Mal, dass ich es in der Reihenfolge der row_num von Veranstaltungen für jedes Paar müssen also muss ich das Aggregat für (1,2), (2,3), (3,4)...

Irgendwelche Ideen, wenn dies möglich ist? Auch muss nicht genau sein, kann ich mit Duplikaten umgehen, und mit type_1 und type_2 Spalten eine vorhandene Zeile in einer anderen Reihenfolge zurückgeben. Ich brauche nur einen Weg, diese Werte zumindest zu erreichen.

+1

'JOIN' die Daten wieder in sich auf' t1. row_num = t2.row_num + 1', um jedes Ereignispaar in der sequentiellen Reihenfolge zu erhalten. – Serg

+0

Danke, perfekt. –

Antwort

1

Was ist mit einem self join? Es würde wie folgt aussehen:

SELECT 
    t1.type 
    , t2.type 
    , ABS(t1.created_at - t2.created_at) AS time_diff 
FROM your_table t1 
INNER JOIN your_table t2 
ON t1.row_num = t2.row_num + 1 
+0

Perfekt, danke! –

1
select type_1, 
     type_2, 
     created_at_2-created_at_1 as time_distance 
from 
(select 
type type_1, 
lead(type,1) over (order by row_num) type_2, 
created_at created_at_1, 
lead(created_at,1) over (order by row_num) created_at_2 
from table_name) temp 
where type_2 is not null 
1

Sie die LAG Fensterfunktion verwenden können, um den aktuellen Wert mit dem vorherigen zu vergleichen:

with 
    t(type,created_at) as (
    values 
     ('ordersPage', '2015-07-21 11:32:40.568+12'::timestamptz), 
     ('getQuote', '2015-07-21 15:49:47.072+12'), 
     ('completeBrief', '2015-07-23 01:00:15.341+12'), 
     ('sendBrief', '2015-07-24 08:59:42.41+12'), 
     ('sendQuote', '2015-07-24 18:43:15.967+12'), 
     ('acceptQuote', '2015-08-03 04:40:20.573+12')) 

select *, EXTRACT(EPOCH FROM created_at - lag(created_at) over (order by created_at)) 
from t 
order by created_at