2009-05-18 27 views
6

Tôi có một cơ sở dữ liệu mysql lưu trữ một số dấu thời gian. Giả sử rằng tất cả có trong bảng là ID và dấu thời gian. Dấu thời gian có thể được nhân đôi.Làm thế nào để tìm sự khác biệt thời gian trung bình giữa các hàng trong một bảng?

Tôi muốn tìm sự khác biệt thời gian trung bình giữa các hàng liên tiếp không trùng lặp (thời gian). Có cách nào để làm điều đó trong SQL?

Trả lời

29

Nếu bảng của bạn là t, và cột timestamp của bạn là ts, và bạn muốn câu trả lời chỉ trong vài giây:

SELECT TIMESTAMPDIFF(SECOND, MIN(ts), MAX(ts)) 
    /
     (COUNT(DISTINCT(ts)) -1) 
FROM t 

Điều này sẽ nhanh hơn đối với các bảng lớn vì nó không có n-squared JOIN

Điều này sử dụng thủ thuật toán học dễ thương giúp giải quyết vấn đề này. Bỏ qua vấn đề trùng lặp cho thời điểm này. Chênh lệch thời gian trung bình giữa các hàng liên tiếp là chênh lệch giữa dấu thời gian đầu tiên và dấu thời gian cuối cùng, chia cho số hàng -1.

Bằng chứng: Khoảng cách trung bình giữa các hàng liên tiếp là tổng khoảng cách giữa các hàng liên kết, chia cho số hàng liên tiếp. Nhưng tổng của sự khác biệt giữa các hàng liên tiếp chỉ là khoảng cách giữa hàng đầu tiên và hàng cuối cùng (giả sử chúng được sắp xếp theo dấu thời gian). Và số hàng liên tiếp là tổng số hàng -1.

Sau đó, chúng tôi chỉ điều kiện các dấu thời gian được phân biệt.

+0

Cảm ơn, điều này thật tuyệt vời. –

+0

Rực rỡ. Câu trả lời tuyệt vời để nhận được sự trùng lặp có thể có của dấu thời gian. – Bell

+0

Thực hiện tốt. Toán đơn giản luôn là lựa chọn tốt nhất. – Rob

1

Dưới đây là một cách:

select avg(timestampdiff(MINUTE,prev.datecol,cur.datecol)) 
from table cur 
inner join table prev 
    on cur.id = prev.id + 1 
    and cur.datecol <> prev.datecol 

Chức năng timestampdiff cho phép bạn lựa chọn giữa ngày, tháng, giây, và vân vân.

Nếu id không liên tiếp, bạn có thể chọn hàng trước bằng cách thêm một quy tắc rằng không có các hàng khác ở giữa:

select avg(timestampdiff(MINUTE,prev.datecol,cur.datecol)) 
from table cur 
inner join table prev 
    on prev.datecol < cur.datecol 
    and not exists (
     select * 
     from table inbetween 
     where prev.datecol < inbetween.datecol 
     and inbetween.datecol < cur.datecol) 
    ) 
2

Are của ID liền kề?

Bạn có thể làm một cái gì đó như thế nào,

SELECT 
     a.ID 
     , b.ID 
     , a.Timestamp 
     , b.Timestamp 
     , b.timestamp - a.timestamp as Difference 
FROM 
    MyTable a 
    JOIN MyTable b 
      ON a.ID = b.ID + 1 AND a.Timestamp <> b.Timestamp 

Điều đó sẽ cung cấp cho bạn một danh sách các thời gian khác nhau trên mỗi cặp liên tiếp liên tiếp ...

Sau đó, bạn có thể bọc rằng trong một nhóm AVG. ..

+0

cố định. –

+0

OK, nhưng điều này sẽ làm việc iff các id là tiếp giáp. Trên thực tế câu trả lời từ Nick là tốt hơn tôi đoán. –

Các vấn đề liên quan