编程语言
首页 > 编程语言> > java-获取具有多个状态的时间戳之间的平均值

java-获取具有多个状态的时间戳之间的平均值

作者:互联网

我正在尝试收集有关数据的简单统计信息,例如服务在线的时间,服务离线的时间,平均值等.我已经找到了一些解决方案,但是它们都依赖于某些事物,例如行被背对背(ROW_NUMBER -1)或只有两种状态.

我的数据总是以事实日志的形式出现(即没有实时数据).我要找出的最大问题是存在两个以上的州.当前,可能存在四种不同的状态(启用,禁用,活动,不活动),我希望能够收集每种状态的数据.

我一次为数据提供了一行,其中包含服务名称,旧状态,新状态和时间戳.当前,数据存储在单个表中.我无法更改数据的提供方式,但是可以更改数据的存储方式,并且我开始认为该表是我的主要缺点.

这是当前数据可能如何在我的表中显示的示例:

CREATE TABLE IF NOT EXISTS statusupdates (
  sid int UNIQUE, 
  fullname VARCHAR(64), 
  oldstatus VARCHAR(16), 
  newstatus VARCHAR(16), 
  time TIMESTAMP);

INSERT INTO statusupdates VALUES
(null, 'fictHTTP', 'Off', 'On', '2017-01-01 02:20:00'),
(null, 'faked', 'On', 'Inactive', '2017-01-01 02:25:00'),
(null, 'ipsum', 'Inactive', 'On', '2017-01-01 02:30:00'),
(null, 'resultd', 'On', 'Inactive', '2017-01-01 02:35:00'),
(null, 'ipsum', 'On', 'Active', '2017-01-01 02:40:00'),
(null, 'fictHTTP', 'On', 'Active', '2017-01-01 02:45:00'),
(null, 'faked', 'Inactive', 'Off', '2017-01-01 02:50:00'),
(null, 'ipsum', 'Active', 'Off', '2017-01-01 02:55:00'),
(null, 'resultd', 'Inactive', 'Off', '2017-01-01 03:00:00');

我相信我发现的一种方法是将其缩小到一项,例如结果.诸如SELECT全名,newstatus,FROM状态更新之类的内容WHERE fullname =’resultd’ORDER BY time DESC;.然后使用该数据,使用相同的方法进行另一次查询,但是向前走一步(因为它是降序排列),并从该记录中获取newstatus.当我键入时,似乎草率.

或者,获取oldstatus并在第二个查询中,使用它来查找以下记录的newstatus.但同样,这可能是草率的.

我知道还有一种方法可以将这两个理论查询结合起来.因此,总而言之,我的想法太过分了,请原谅我!最后,我想查看每种状态的统计信息,例如总时间,平均时间等.我目前最大的障碍是获取查询以提供结果,例如,ipsum的每个时间戳记条目的输入方式都可以使我获得上一个条目的持续时间,并重复该操作直到它遍历所有记录.

或者,也许是我完全考虑了这个问题,并且通过将所有数据放入一个表中而使其变得过于复杂-到目前为止,我在该项目中已经为不相关的项目做过两次.

附加思想:在一个实例中,我可以执行select old_status,new_status,time FROM statusupdates WHERE time =’2017-01-01 03:00:00’然后我可以像这样使用old_status,SELECT old_status,new_status,time FROM statusupdates WHERE时间< 'timeStamp'和new_status ='oldStatus'然后减去两个时间戳,这将为我提供一个示例的数据.但是,接下来该如何做,以及下一步,直到全部成功. 更新,另一种想法:结合您一些出色的建议,向后读取日志该怎么办?没关系,在那一点上,无论阅读什么方向都没关系.遇到状态时,请创建不完整的记录.它将包含old_status和time_stamp作为end_time.然后,当再次遇到该服务时,它将检查new_status = old_status,并使用time_stamp作为start_time更新记录. 但这似乎会导致大量开销.必须检查每条记录以查看它是否存在,如果不存在,则更新一条.也许那还算不错?

解决方法:

您可以访问数据库中的窗口功能吗?如果是这样,则可以获取每条记录的下一行的值(按全名分区):

  select  fullname,
          newstatus,
          avg( time_diff ) as avg_time
  from    (
            select  fullname,
                    oldstatus,
                    newstatus,
                    /* get the time value of the next row for this fullname record */
                    lead( time ) over( 
                      partition by fullname 
                      order by time 
                      rows between 1 following and 1 following 
                    ) as next_time,
                    time,
                    next_time - time as time_diff
            from    statusupdates
          ) as a
   group by fullname,
          newstatus

编辑

在没有窗口函数的情况下,您可以以更复杂的方式获取next_time:

select a.*,
       b.next_time
from   statusupdates as a
       left join
       (
       select a.fullname,
              a.time,
              min( b.time ) as next_time
       from   statusupdates as a
              left join
              statusupdates as b
              on a.fullname = b.fullname
              and a.time < b.time
       group by a.fullname,
              a.time
       ) as b
       on a.fullname = b.fullname
       and a.time = b.time
;

标签:hsqldb,usage-statistics,sql,java
来源: https://codeday.me/bug/20191026/1935754.html