具有分层数据的连续行中的MySQL时差

时间:2017-01-06 03:37:52

标签: mysql

如何使用分层数据查询连续行之间的时差?例如,我想从下表中获取:

+-------+----------+---------------------+
| group_id |  event   |     event_time      |
+-------+----------+---------------------+
|     1 | alarm    | 2016-12-01 17:53:12 |
|     1 | alarm    | 2016-12-01 17:59:43 |
|     2 | purchase | 2016-11-29 09:49:47 |
|     2 | purchase | 2016-11-29 09:53:51 |
|     2 | purchase | 2016-11-29 09:57:59 |
|     2 | alarm    | 2016-11-29 10:01:02 |
|     2 | alarm    | 2016-11-29 10:13:27 |
|     2 | purchase | 2016-11-29 10:15:00 |
|     2 | purchase | 2016-11-29 10:16:24 |
+-------+----------+---------------------+

为:

+-------+----------+---------------------+------------+
| group_id |  event   |     event_time      | time_delta |
+-------+----------+---------------------+------------+
|     1 | alarm    | 2016-12-01 17:53:12 | 0          |
|     1 | alarm    | 2016-12-01 17:59:43 | 00:06:31   |
|     2 | purchase | 2016-11-29 09:49:47 | 0          |
|     2 | purchase | 2016-11-29 09:53:51 | 00:04:04   |
|     2 | purchase | 2016-11-29 09:57:59 | 00:04:08   |
|     2 | alarm    | 2016-11-29 10:01:02 | 0          |
|     2 | alarm    | 2016-11-29 10:13:27 | 00:12:25   |
|     2 | purchase | 2016-11-29 10:15:00 | 0          |
|     2 | purchase | 2016-11-29 10:16:24 | 00:01:24   |
+-------+----------+---------------------+------------+

上述数据仅供参考;我的数据实际上有很多组和很多事件。所以基本上,只要group_id和事件在连续的行中相同,我就要计算时差。

2 个答案:

答案 0 :(得分:0)

您可以通过以下方式获取给定组的上一次:

select t.*,
       (select t2.time_delta
        from t t2
        where t2.group_id = t.group_id and
              t2.event = t.event and
              t2.event_time < t.event_time
        order by t2.event_time desc
        limit 1
       ) as prev_event_time
from t;

然后,您可以通过多种方式获得时差,例如:

select t.*, timediff(event_time, prev_event_time)
from (select t.*,
             (select t2.time_delta
              from t t2
              where t2.group_id = t.group_id and
                    t2.event = t.event and
                    t2.event_time < t.event_time
              order by t2.event_time desc
              limit 1
             ) as prev_event_time
      from t
     ) t

答案 1 :(得分:0)

使用用户定义的变量尝试此操作:

SELECT 
    group_id, event, event_time, diff time_delta
FROM
    (SELECT 
        t1.*,
            CASE
                WHEN @event = event AND @group = group_id THEN TIME_FORMAT(TIMEDIFF(event_time, @et), '%H:%i:%s')
                ELSE 0
            END diff,
            @event:=event,
            @group:=group_id,
            @et:=event_time
    FROM
        (SELECT 
        *
    FROM
        your_table
    ORDER BY group_id , event_time) t1
    CROSS JOIN (SELECT @event:='', @group:=- 1, @et:='') t2) t;

@et变量将先前的event_time存储在group_id和event的每个组中。