在mysql数据库中找到最长的连续序列

时间:2018-07-31 14:31:16

标签: mysql sql timestamp

我想在包含日志文件的数据库中找到最长的连续序列。 该文件具有以下结构:

select * from log;
+---------------+-------------------+---+
|sequence_number|timestamp          |...|
|---------------+-------------------+---+
|1              |2012-02-21 13:31:21|...|
|2              |2012-02-21 13:31:58|...|
|3              |2012-02-21 13:32:01|...|
|4              |2012-02-21 13:33:24|...|
|5              |2012-02-25 05:41:12|...|
|6              |2012-02-25 05:41:51|...|

etc...

我想找到最长连续序列条目的时间段的开始日期和结束日期,其中两行之间的时间差小于一分钟。上面的数据库的结果应该是:

+-------------------+-------------------+----+
|start_date         |end_date           |size|
+-------------------+-------------------+----+
|2012-02-21 13:31:21|2012-02-21 13:32:01|3   |
|2012-02-25 05:41:21|2012-02-25 05:41:51|2   |
|2012-02-21 13:33:24|2012-02-21 13:33:24|1   |

我检查了一些提示,但是可以找到适合mysql(MariaDB 10.1.23)的解决方案

希望有人可以提供帮助,谢谢!

2 个答案:

答案 0 :(得分:2)

这是一个主意:

DROP TABLE IF EXISTS log;

CREATE TABLE  log
    (`sequence_number` int, `timestamp` timestamp)
;

INSERT INTO  log
    (`sequence_number`, `timestamp`)
VALUES
    (1, '2012-02-21 13:31:21'),
    (2, '2012-02-21 13:31:58'),
    (3, '2012-02-21 13:32:01'),
    (4, '2012-02-21 13:33:24'),
    (5, '2012-02-25 05:41:12'),
    (6, '2012-02-25 05:41:51')
;

 SELECT MIN(timestamp) start
      , MAX(timestamp) end
      , COUNT(*) total
   FROM 
      ( SELECT l.*
             , CASE WHEN @prevx > timestamp - INTERVAL 60 SECOND THEN @ix:=@ix+1 ELSE @ix:=1 END i
             , CASE WHEN @ix=1 THEN @jx:=@jx+1 ELSE @jx:=@jx END j
             , @prevx := timestamp
          FROM log l
             , (SELECT @prevx:=null,@ix:=1,@jx:=0) vars
         ORDER  
            BY l.timestamp
      ) x
  GROUP 
     BY j
  ;

给出以下输出:

+---------------------+---------------------+-------+
| start               | end                 | total |
+---------------------+---------------------+-------+
| 2012-02-21 13:31:21 | 2012-02-21.13:32:01 |     3 |
| 2012-02-21 13:33:24 | 2012-02-21.13:33:24 |     1 |
| 2012-02-25 05:41:12 | 2012-02-25.05:41:51 |     2 |
+---------------------+---------------------+-------+

http://sqlfiddle.com/#!9/777360/19

答案 1 :(得分:0)

在V8.0之前的版本中,您可以使用变量:

select min(timestamp), max(timestamp), count(*)
from (select l.*,
             (case when (@tmp_prevts := @prevts) = NULL then NULL
                   when (@prevts := timestamp) = NULL then NULL
                   when @tmp_prevts > timestamp - interval 1 minute then @grp
                   else (@grp := @grp + 1)
              end) as grp
      from (select l.*
            from log l
            order by l.timestamp
           ) l cross join
           (select @prevts := '', @grp := 0) params
     ) l
group by grp
order by count(*) desc;