答:
题主你好,
我的思路是要先清洗数据,把时间按照30分钟和状态进行分组,例如00点到30点算到00点,30点到60算到30。
有了这个数据,就可以分组算出最大时间和最小时间,就是持续时长。当然这个持续时长是根据每个状态划分的 。
最后再来判断小于30分钟的待机数,使用LAG()函数获取上一条是否是正常。如是是,则把他也划分为正常数据。这样我们最多把正常前面30分钟的待机划分为正常了(这也是我们按30分组的原因)

当然我写成一个sql了,如果必要我们可以用视图,也可以使用存储过程。
数据是我造的,希望对你有帮助。有疑问可以私聊
附sql:
```sql
SELECT CONCAT(date,time, '') 时间段,
MAX( cj_date ),
min( cj_date ),STATUS,TIMESTAMPDIFF(MINUTE, min( cj_date ),MAX( cj_date )) 状态持续时长
FROM
(
SELECT
*,
SUBSTRING( DATE_FORMAT( cj_date, '%Y-%m-%d %H:%i' ), 1, 14 ) date,
SUBSTRING( DATE_FORMAT( cj_date, '%Y-%m-%d %H:%i' ), 15, 1 ) '分钟(10位数字)',
CASE
WHEN SUBSTRING( DATE_FORMAT( cj_date, '%Y-%m-%d %H:%i' ), 15, 1 ) > 3 THEN
'30' ELSE '00'
END time ,
CASE
WHEN num > 100 THEN
'正常'
WHEN num = 0 THEN
'停机' ELSE '待机'
END STATUS
FROM ct_info
ORDER BY cj_date ) aa
GROUP BY date, time, STATUS
```

这样呢 感觉写回去了,把相邻状态一致的标记出来。这是一问一答吗。发不出去。