在 MySQL 中分组 'islands' 5.7

Grouping 'islands' in MySQL 5.7

我正在努力解决一个我认为很简单的 'gaps and island' 问题。

转这个结果集:

7:18    WORK
7:19    WORK
7:20    WORK
7:29    BREAK
7:30    BREAK
7:31    WORK
7:32    WORK
7:33    IDLE
7:34    IDLE
7:35    IDLE
7:36    IDLE

为此:

from_timestamp  until_timestamp status  records_in_island
7:18    7:24    WORK    6
7:29    7:32    BREAK   3
7:31    7:32    WORK    2
7:33    7:36    IDLE    4

或者基本上显示:

这是一个带有数据的 dbfiddle: https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=a15cc8325ef4bc743df3208f8f328b9a

我在找到的空白和孤岛解决方案中找不到任何解决方案。我正在使用 MySQL 5.7(由于 AWS Aurora 限制)所以不能使用 WITH 或其他 MySQL 8.0 语法。

如有任何帮助,我们将不胜感激。

也许最简单的方法是使用 where 过滤掉“前一个”值与第 2 列具有相同值的值。假设这些值是 date/time 个值并且恰好在一个值上对齐分钟:

select t.*
from (select t.*,
             (select t2.status
              from test t2
              where t2.timestamp < t.timestamp
              order by t2.timestamp desc
              limit 1
             ) as prev_status
      from test t
     ) t
where not prev_status <=> status;

Here 是一个 db<>fiddle.

另一种方法是在 SELECT 语句中使用变量:

SELECT event, MIN(event_time) AS event_time, COUNT(*) AS cnt
FROM (
  SELECT 
    CASE WHEN @e = event THEN @c ELSE @c := @c + 1 END AS id,
    event_time,  @e := event AS event
  FROM events, (SELECT @c := 0, @e := '') vars
  ORDER BY event_time
) t  
GROUP BY id, event
ORDER BY event_time

fiddle

但由于 MySQL 8 在表达式中设置用户变量已被弃用,并将在未来的版本中删除。