我有一个程序,每分钟通过PING检查网络中的计算机的状态。 每次它都会向DB插入一个新行,如下所示(我使用postgresql)
id_status status checking_time(timestamp) id_device(int)
1 OK '2017-01-01 00:00:00' 1
2 OK '2017-01-01 00:00:00' 2
3 OK '2017-01-01 00:00:00' 3
4 Failed '2017-01-01 00:01:00' 1
5 OK '2017-01-01 00:01:00' 2
6 OK '2017-01-01 00:01:00' 3
7 Failed '2017-01-01 00:02:00' 1
8 OK '2017-01-01 00:02:00' 2
9 OK '2017-01-01 00:02:00' 3
10 Failed '2017-01-01 00:03:00' 1
11 OK '2017-01-01 00:03:00' 2
12 OK '2017-01-01 00:03:00' 3
13 OK '2017-01-01 00:04:00' 1
14 OK '2017-01-01 00:04:00' 2
15 OK '2017-01-01 00:04:00' 3
我希望结果如下
status from_time(timestamp) to_time(timestamp) id_device(int)
OK '2017-01-01 00:00:00' '2017-01-01 00:01:00' 1
Failed '2017-01-01 00:01:00' '2017-01-01 00:04:00' 1
OK '2017-01-01 00:04:00' NOW 1
OK '2017-01-01 00:00:00' NOW 2
OK '2017-01-01 00:00:00' NOW 3
如何获得此输出?。
答案 0 :(得分:1)
这是差距和岛屿问题。它可以解决如下:
select t.status,
t.from_time,
coalesce(CAST(lead(from_time) over (partition by id_device order by from_time) AS varchar(20)), 'NOW') to_date,
t.id_device
from
(
select t.status, min(checking_time) from_time, t.id_device
from
(
select *, row_number() over (partition by id_device, status order by checking_time) -
row_number() over (partition by id_device order by checking_time) grn
from data
) t
group by t.id_device, grn, t.status
) t
order by t.id_device, t.from_time
<强> dbffile demo 强>
关键是最嵌套的子查询,我使用两个row_number
函数来隔离设备上连续出现的相同状态。一旦获得grn
值,其余部分就很容易了。
<强>结果强>
status from_time to_time id_device
------------------------------------------------------------
OK 2017-01-01 00:00:00 2017-01-01 00:01:00 1
Failed 2017-01-01 00:01:00 2017-01-01 00:04:00 1
OK 2017-01-01 00:04:00 NOW 1
OK 2017-01-01 00:00:00 NOW 2
OK 2017-01-01 00:00:00 NOW 3
类似问题