我有一个如下所示的数据库表
___________
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条记录。我怎样才能做到这一点?
答案 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 |
+----+-------+