【问题标题】:MySQL return first and last record for consecutive identical resultsMySQL 返回连续相同结果的第一条和最后一条记录
【发布时间】:2015-01-13 15:19:13
【问题描述】:

我正在使用 MySQL 并且有一个名为“结果”的表,它存储了一个监视器的结果,该监视器确定服务在特定时间是启动还是停止。

+-----------+------------+---------------------+--------+
| 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     |
+-----------+------------+---------------------+--------+

我想得到一个结果表,查看给定服务的结果,并返回它第一次记录为关闭的时间和最后一次(连续),反之亦然。这将帮助我记录服务的停机时间。

我正在寻找的结果应该是这样的。

对于 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 技能不是特别高级。我该如何处理?

【问题讨论】:

  • 谢谢!我看过这个解决方案,但结果没有串联成一行。我想我对主键是其中一个解决方案中的时间戳感到困惑。

标签: mysql sql monitoring rows


【解决方案1】:

解决这个问题的最简单方法是使用变量,我认为最简单的方法是添加两个变量,一个是“向上”的数量,另一个是任何给定行的“向下”数量。给定的上升序列对于前面的“下降”的数量具有恒定值,反之亦然。此逻辑可用于聚合。

结果查询是:

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 2014-02-13
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    相关资源
    最近更新 更多