MySQL return 连续相同结果的第一个和最后一个记录
MySQL return first and last record for consecutive identical results
我正在使用 MySQL 并有一个名为 'results' 的 table,它存储监视器的结果,该监视器确定服务在特定时间是启动还是关闭。
+-----------+------------+---------------------+--------+
| result_id | service_id | time_stamp | result |
+-----------+------------+---------------------+--------+
| 1 | 1 | 0000-00-00 00:01:00 | down |
| 2 | 1 | 0000-00-00 00:02:00 | up |
| 3 | 1 | 0000-00-00 00:03:00 | up |
| 4 | 1 | 0000-00-00 00:04:00 | up |
| 5 | 1 | 0000-00-00 00:05:00 | down |
| 6 | 1 | 0000-00-00 00:06:00 | down |
| 7 | 1 | 0000-00-00 00:07:00 | up |
| 8 | 1 | 0000-00-00 00:08:00 | down |
| 9 | 1 | 0000-00-00 00:09:00 | up |
| 10 | 2 | 0000-00-00 00:03:00 | up |
+-----------+------------+---------------------+--------+
我想获得 table 的结果,查看给定服务的结果以及 return 第一次记录为停机的时间和最后一次(连续)和反之亦然反之亦然。这将帮助我记录服务的停机时间。
我要查找的结果如下所示。
对于service_id 1...
+-----------------------+---------------------+--------+
| start_time | end_time | result |
+-----------------------+---------------------+--------+
| 0000-00-00 00:01:00 | 0000-00-00 00:01:00 | down |
| 0000-00-00 00:02:00 | 0000-00-00 00:04:00 | up |
| 0000-00-00 00:05:00 | 0000-00-00 00:06:00 | down |
| 0000-00-00 00:07:00 | 0000-00-00 00:07:00 | up |
| 0000-00-00 00:08:00 | 0000-00-00 00:08:00 | down |
| 0000-00-00 00:09:00 | 0000-00-00 00:09:00 | up |
+-----------------------+---------------------+--------+
我可以很容易地在 Java 或 PHP 中获取此信息,但我更愿意使用 SQL 查询。我的 SQL 技能不是特别高。我该如何处理?
最简单的方法是使用变量,我认为最简单的方法是添加两个变量,一个是 "up" 的数量,另一个是 "down" 的数量任何给定的行。给定的 ups 序列对于前面的 "down"s 的数量具有恒定值,反之亦然。此逻辑可用于聚合。
结果查询是:
select result, min(time_stamp) as start_time, max(time_stamp) as end_time
from (select r.*,
(@ups := @ups + (result = 'up')) as ups,
(@downs := @downs + (result = 'down')) as downs
from results r cross join
(select @ups := 0, @downs := 0) vars
where service_id = 1
order by time_stamp
) r
group by result, (case when result = 'up' then downs else ups end);
我正在使用 MySQL 并有一个名为 'results' 的 table,它存储监视器的结果,该监视器确定服务在特定时间是启动还是关闭。
+-----------+------------+---------------------+--------+
| result_id | service_id | time_stamp | result |
+-----------+------------+---------------------+--------+
| 1 | 1 | 0000-00-00 00:01:00 | down |
| 2 | 1 | 0000-00-00 00:02:00 | up |
| 3 | 1 | 0000-00-00 00:03:00 | up |
| 4 | 1 | 0000-00-00 00:04:00 | up |
| 5 | 1 | 0000-00-00 00:05:00 | down |
| 6 | 1 | 0000-00-00 00:06:00 | down |
| 7 | 1 | 0000-00-00 00:07:00 | up |
| 8 | 1 | 0000-00-00 00:08:00 | down |
| 9 | 1 | 0000-00-00 00:09:00 | up |
| 10 | 2 | 0000-00-00 00:03:00 | up |
+-----------+------------+---------------------+--------+
我想获得 table 的结果,查看给定服务的结果以及 return 第一次记录为停机的时间和最后一次(连续)和反之亦然反之亦然。这将帮助我记录服务的停机时间。
我要查找的结果如下所示。
对于service_id 1...
+-----------------------+---------------------+--------+
| start_time | end_time | result |
+-----------------------+---------------------+--------+
| 0000-00-00 00:01:00 | 0000-00-00 00:01:00 | down |
| 0000-00-00 00:02:00 | 0000-00-00 00:04:00 | up |
| 0000-00-00 00:05:00 | 0000-00-00 00:06:00 | down |
| 0000-00-00 00:07:00 | 0000-00-00 00:07:00 | up |
| 0000-00-00 00:08:00 | 0000-00-00 00:08:00 | down |
| 0000-00-00 00:09:00 | 0000-00-00 00:09:00 | up |
+-----------------------+---------------------+--------+
我可以很容易地在 Java 或 PHP 中获取此信息,但我更愿意使用 SQL 查询。我的 SQL 技能不是特别高。我该如何处理?
最简单的方法是使用变量,我认为最简单的方法是添加两个变量,一个是 "up" 的数量,另一个是 "down" 的数量任何给定的行。给定的 ups 序列对于前面的 "down"s 的数量具有恒定值,反之亦然。此逻辑可用于聚合。
结果查询是:
select result, min(time_stamp) as start_time, max(time_stamp) as end_time
from (select r.*,
(@ups := @ups + (result = 'up')) as ups,
(@downs := @downs + (result = 'down')) as downs
from results r cross join
(select @ups := 0, @downs := 0) vars
where service_id = 1
order by time_stamp
) r
group by result, (case when result = 'up' then downs else ups end);