2013-06-25 48 views
15

Tôi có một bảng như thế này,chức năng LAG và GROUP BY

event_id |   date   
----------+------------------------ 
    1703702 | 2013-06-25 07:50:57-04 
    3197588 | 2013-06-25 07:51:57-04 
60894420 | 2013-06-25 07:52:57-04 
60894420 | 2013-06-25 07:53:57-04 
    183503 | 2013-06-25 07:54:57-04 
63116743 | 2013-06-25 07:55:57-04 
63110451 | 2013-06-25 07:56:57-04 
63116743 | 2013-06-25 07:57:57-04 
63116743 | 2013-06-25 07:58:57-04 

Tôi muốn áp dụng các chức năng lag mà còn là một nhóm bằng cách để tôi có thể tìm ra các khoảng thời gian giữa bất kỳ event_id cụ thể.

Tôi muốn một cái gì đó như thế này:

SELECT event_id, difference 
FROM ( 
    SELECT event_id, date - lag(date) over (order by date) as 
    difference FROM table GROUP BY event_id 
) t; 

Tôi không thể tuy nhiên sử dụng GROUP BY với chức năng LAG. Tôi muốn có kết quả tương tự như sau:

63116743, {120, 60} 
60894420, {60} 
... 
... 

Vì vậy, có khoảng thời gian 120 giây và 60 giây giữa các sự kiện cho id đầu tiên và cửa sổ 60 giây cho id thứ hai.

Có cách nào để thực hiện việc này không? Định dạng đầu ra không quá quan trọng miễn là tôi có thể đưa nó vào một mảng ở cuối. Tôi đang sử dụng Postgres 9.1

+0

Xin lỗi, nhưng tôi không hiểu ý nghĩa của đầu ra. 120? 60? của cái gì? nó dường như không xuất phát từ dữ liệu bạn cho thấy. –

+0

Lựa chọn phụ trong câu hỏi của bạn không thêm bất kỳ thứ gì vào truy vấn - bạn đang thực hiện một 'SELECT *' từ nó một cách hiệu quả, giống như chỉ chạy truy vấn bên trong. – IMSoP

+0

@depesz \t Đó là khoảng thời gian được tính bằng giây: 120 giây trong khoảng thời gian từ '2013-06-25 07: 55: 57-04' và '2013-06-25 07: 57: 57-04', sau đó là 60 giây giữa thời gian đó và '2013 -06-25 07: 58: 57-04 ', chỉ so sánh các sự kiện có cùng ID. – IMSoP

Trả lời

19
WITH diffs as (
    SELECT 
     event_id, 
     date - lag(date) over (partition BY event_id ORDER BY date) as difference 
    FROM 
     TABLE 
) 
SELECT 
    event_id, 
    array_agg(difference) as all_diffs 
FROM 
    diffs 
GROUP BY event_id; 

Nên hoạt động.

+0

Và đây là một SQLFiddle để chứng minh nó: http://www.sqlfiddle.com/#!1/c22fc/4 ('array_agg' dường như phá vỡ SQLFiddle vì một lý do nào đó, vì vậy tôi đã sử dụng' string_agg' để kiểm tra kết quả) – IMSoP

+1

Oh, và để diễn tả trong vài giây, 'EXTRACT (' epoch 'FROM ...) ': http://www.sqlfiddle.com/#!1/c22fc/6 – IMSoP

+0

Tôi hiểu lầm câu hỏi và không bao gồm 'PARTITION BY'; Tôi đã chuẩn bị SQLFiddle để tìm ra nó, nhưng bạn đánh tôi với nó :) – IMSoP