Question

I have a table like:

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

I need to output the data "grouped" by the status, and sorted by time. The trick is that I need the groupings in chunks for each time the status changes, with the fields: MIN(time), status

So for the example data above I'd need an output like

MIN(time)  | status
1390836600 | 1
1390836610 | 0
1390836620 | 1

This is not the behaviour of GROUP BY, which would just group ALL rows with the same status and only output 2 rows. But is something like this possible?

Was it helpful?

Solution

This (grouping of continuous ranges) is called gaps-and-islands problem and can be effectively solved by using analytic functions (specifically ROW_NUMBER()) which MySQL still has no support for.

But you can emulate ROW_NUMBER() with session variables in the following way

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

Output:

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

Here is a SQLFiddle demo

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top