MySQL组按列值分块,按其他列排序

时间:2014-01-27 14:57:04

标签: mysql sql gaps-and-islands

我有一张表:

time       | status
1390836600 | 1
1390836605 | 1
1390836610 | 0
1390836615 | 0
1390836620 | 1
1390836625 | 1
1390836630 | 1

我需要输出数据"分组"按状态,按时间排序。诀窍是,每次状态更改时,我都需要以块的形式进行分组,并使用以下字段:MIN(time), status

因此,对于上面的示例数据,我需要像

这样的输出
MIN(time)  | status
1390836600 | 1
1390836610 | 0
1390836620 | 1

这不是GROUP BY的行为,它只会将具有相同状态的所有行分组,并且只输出2行。但这样的事情可能吗?

1 个答案:

答案 0 :(得分:2)

这(连续范围的分组)被称为gaps-and-islands问题,可以通过使用MySQL仍然不支持的分析函数(特别是ROW_NUMBER())来有效地解决。

但您可以通过以下方式使用会话变量模拟ROW_NUMBER()

SELECT MIN(time) time, status
  FROM
(
  SELECT time, status,
         @n := @n + 1 rnum,
         @g := IF(status = @s, @g + 1, 1) rnum2,
         @s := status
    FROM table1 CROSS JOIN (SELECT @n := 0, @g := 0, @s := NULL) i
   ORDER BY time 
) q
 GROUP BY rnum - rnum2

输出:

|       TIME | STATUS |
|------------|--------|
| 1390836600 |      1 |
| 1390836610 |      0 |
| 1390836620 |      1 |

这是 SQLFiddle 演示