2017-06-05 72 views
-2

我有一個像下面如何從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條記錄。我怎樣才能做到這一點?

+4

你嘗試過什麼嗎? –

+0

「大於任何其他連續記錄」是否意味着您想要記錄數最多的連續序列? –

+0

我認爲這被稱爲「最長的連勝」問題。 – Strawberry

回答

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 | 
+-------+-------+-------+ 

然後,使用從上述的第一行作爲另一派生表,加入到原始表中從最小值到最大值的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 | 
+----+-------+ 
+0

請注意,此解決方案假定只能有* 1 *最大連勝。 – Strawberry

+0

@Strawberry,不,它只是*返回*一個最大連勝。如果你有多於一個綁定的最大長度,你會得到其中一個。 OP的要求並沒有針對這種情況。 –

+0

@BillKarwin,謝謝你的回答。但是我通過檢索所有記錄來解決我的問題,如果條件(先前和現在以及下一個速度爲零)。 – Hari