2016-05-10 3 views
0

У меня есть набор данных, который имеет type столбец и столбец с created_at времени. У меня уже есть запрос, который вытаскивает соответствующие данные из базы данных, и это данные, которые возвращаются.Агрегирование несколько строк больше, чем когда-то

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 

Номер строки возвращается из стандартной функции числа строк в Postgres

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

То, что я хочу сделать, это какое-то образом агрегировать эти данные так получить временное расстояние между каждым событием, так что выходные данные может выглядеть как этот

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 

время расстояние будет плавать в миллисекундах, в других запросах я использую что-то вроде этого, чтобы получить разницу во времени ,

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

Но на этот раз мне это нужно для каждой пары событий в последовательном порядке ROW_NUM поэтому мне нужен агрегат для (1,2), (2,3), (3,4)...

Любых идей, если это возможно? Также не должен быть точным, я могу иметь дело с дубликатами, и с type_1 и type_2 столбцов возвращением существующей строки в другом порядке. Мне просто нужен способ, по крайней мере, получить эти значения выше.

+1

'JOIN' возвращаемые данные себе на' t1. row_num = t2.row_num + 1', чтобы получить каждую пару событий в последовательном порядке. – Serg

+0

Спасибо, отлично. –

ответ

1

насчет self join? Это будет выглядеть следующим образом:

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

Отлично, спасибо! –

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

Вы можете использовать функцию окна LAG сравнить текущее значение с предыдущим:

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