如何从mysql中仅获取连续记录?

时间:2017-06-05 14:21:20

标签: mysql

我有一个如下所示的数据库表

___________
id |  speed
-----------
1  |   3
2  |   2
3  |   0
4  |   0
5  |   0
6  |   2
7  |   0
8  |   0
9  |   2
10 |   0

现在我想得到速度为0但只有3到5的记录,它们是连续的并且比任何其他连续记录都要大。我不想要7,8条记录或第10条记录。我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

可能最快的方法是使用MySQL会话变量来增加"组"每次速度变化时,在扫描行时都会这样。

select n.*, @groupid:=IF(@prev_speed=speed,@groupid,@groupid+1) as groupid, @prev_speed:=speed
from (select @groupid:=0, @prev_speed=-1) _init
cross join n
order by id;

+----+-------+---------+--------------------+
| id | speed | groupid | @prev_speed:=speed |
+----+-------+---------+--------------------+
|  1 |     3 | 1       |                  3 |
|  2 |     2 | 2       |                  2 |
|  3 |     0 | 3       |                  0 |
|  4 |     0 | 3       |                  0 |
|  5 |     0 | 3       |                  0 |
|  6 |     2 | 4       |                  2 |
|  7 |     0 | 5       |                  0 |
|  8 |     0 | 5       |                  0 |
|  9 |     2 | 6       |                  2 |
| 10 |     0 | 7       |                  0 |
+----+-------+---------+--------------------+

然后使用上述查询作为派生表,计算每组的最低和最高ID以及行数。按行数对组进行排序。

select min(id) as minid, max(id) as maxid, count(*) as count
from (
    select n.*, @groupid:=IF(@prev_speed=speed,@groupid,@groupid+1) as groupid, @prev_speed:=speed
    from (select @groupid:=0, @prev_speed=-1) _init
    cross join n
    order by id
) as t1
group by t1.groupid
order by count desc;

+-------+-------+-------+
| minid | maxid | count |
+-------+-------+-------+
|     3 |     5 |     3 |
|     7 |     8 |     2 |
|     1 |     1 |     1 |
|     2 |     2 |     1 |
|     6 |     6 |     1 |
|     9 |     9 |     1 |
|    10 |    10 |     1 |
+-------+-------+-------+

然后使用上面的第一行作为另一个派生表,连接到原始表,以获取从min到max id范围内的行。

select n.*
from (
        select min(id) as minid, max(id) as maxid, count(*) as count
        from (
                select n.*, @groupid:=IF(@prev_speed=speed,@groupid,@groupid+1) as groupid, @prev_speed:=speed
                from (select @groupid:=0, @prev_speed=-1) _init
                cross join n
                order by id
        ) as t1
        group by t1.groupid
        order by count desc limit 1
) as t2
inner join n on n.id between t2.minid and t2.maxid

+----+-------+
| id | speed |
+----+-------+
|  3 |     0 |
|  4 |     0 |
|  5 |     0 |
+----+-------+