2012-02-07 75 views
5

我试图获得每个子序列的行数。选择连续记录的数量

最初的表看起来是这样的:

+----+-------------+ 
| id | value  | 
+----+-------------+ 
| 1 | a   | 
| 2 | b   | 
| 3 | b   | 
| 4 | c   | 
| 5 | a   | 
| 6 | a   | 
| 7 | a   | 
| 8 | a   | 
| 9 | c   | 
| 10| c   | 
+----+-------------+ 

查询应返回的项目数的值的每个序列:

+----+-------------+ 
| value | count | 
+----+-------------+ 
| a | 1  | 
| b | 2  | 
| c | 1  | 
| a | 4  | 
| c | 2  | 
+-------+----------+ 

到目前为止,我一直没能来提供解决方案,至少对于大型桌子来说不够快。理想情况下,会有一个“group by”声明,它不会混淆记录的顺序。

+2

这被称为游程长度编码。 – 2012-02-07 11:11:44

+0

重复的http://stackoverflow.com/questions/9172006/how-to-combine-near-same-item-by-sql – flesk 2012-02-07 11:18:02

回答

2
SELECT value, count(*) FROM (
    SELECT value, 
    (CASE WHEN @v != value THEN @i:[email protected]+1 ELSE @i END) gid, 
    @v := value FROM myTable, (SELECT @v:='', @i := 0) vars 
) tbl 
GROUP BY gid 
+0

我认为这是非常关闭...只有一件事。在第一个记录之后的每个记录的变化中,@i将是开始下一个循环的计数。我会将您的ELSE更改为ELSE @i:= 1 ...以表示它正在重置为1,作为刚刚进入的新ID的开始。 – DRapp 2012-02-13 14:23:34

+0

@DRapp:你试过了吗?我认为它按照OP的要求是正常的,而且你的建议会打破它。你需要一个不断增加的计数器,否则你将把相同的值组合在一起,这些值由不同的值组分开。 – flesk 2012-02-13 14:40:36

+0

你是对的......错过了它,你的COUNT是真正的计数器,你的“i”值是每个值之间的周期性变化之间的力量中断......误解了你的“i”变量 – DRapp 2012-02-13 15:39:58