-1

我有以下查询数据:

SELECT * 
FROM MYTABLE 
WHERE tagid = '65'

输出:

   tagid    floatvalue  t_stamp
   -------------------------------
    65  25.51477051 1455897455214
    65  35.71407318 1455897485215
    65  36.05856323 1455897515215
    65  35.72781372 1455897545214
    65  35.99771118 1455897575215
    65  35.87993622 1455897605215
    65  36.23326111 1455897665215
    65  35.8652153  1455897695215
    65  35.73075485 1455897725216
    65  35.94765472 1455897785216
    65  36.36379242 1455897815217
    65  35.93685913 1455897845216
    65  36.64154816 1455898025219
    65  36.44329071 1455898055218
    65  36.07524872 1455898085219
    65  36.40992355 1455898115217
    65  38.13336182 1455898145217

t_stamp列是 Unix 的一个大整数time * 1000

如果机器正在运行,则此数据每约 30 秒(30,000 秒)记录一次。如果它们与前一行的时间差小于两分钟(120,000),我正在尝试查询时间差的总和。如果它大于两分钟,那么我假设机器关闭并且该行将是下一个总和的新开始时间。

我的目标是使用时间戳获得总运行时间的总和。

我完全不知道从哪里开始。我很难试图让这个解释对我有意义,更不用说你们了,如果我把它弄得一团糟,请道歉。

4

2 回答 2

1

如果您没有lag()其他方法可以获取上一个时间戳。

;with step1 as (
    select
        t_stamp,
        case
            when t_stamp - lag(t_stamp) over (partition by tagid order by t_stamp) > 120000
            then 1 else 0
        end as brk
    from mytable
), step2 as (
    select t_stamp, sum(brk) over (partition by tagid order by t_stamp) as grp,
    from step1
)
select
    grp, min(t_stamp) as start_time, max(t_stamp) as end_time,
    max(t_stamp) - min(t_stamp) as total_time
from step2
group by tagid, grp;

这是“差距和岛屿”标题下的一个相当典型的问题。你会发现很多与你的问题相似的例子。

完全巧合的是,我今天发现了十多年前的这篇 Oracle文章。它使用了一种您可能会觉得有趣的稍微不同的方法。

编辑:

这是逻辑的快速分解。

第 1 步使用 将每个标记与前一个值按时间顺序进行比较lag。当它发现一个大于阈值的间隙时,它被标记为 1。所有其他的都为零(null 也可以。)这实际上标志着一个新块的开始,也就是“grp”。

第 2 步以相同的顺序计算运行总计。因此,运行总计仅在每次新块开始时更改,因此块中的每一行都获得相同的值。该值用于group by计算时间差,然后计算为最小和最大时间戳之间的跨度。

于 2016-08-15T20:03:27.700 回答
0

试试光标

declare @sum bigint
declare @t_stamp bigint
declare @last bigint
declare @diff bigint
select @sum = 0
declare MyCursor cursor for select t_stamp from mytable where tagid=65
open MyCursor


fetch next from MyCursor into @t_stamp 
while @@fetch_Status = 0
begin

   if (not (@last is null))
   begin
       select @diff = @t_stamp - @last

       if (@diff < 120000)
       begin
           select @sum = @sum + @diff
       end 
   end
   select @last = @t_stamp

   fetch next from MyCursor into @t_stamp 
end
close MyCursor
deallocate MyCursor

print @sum
于 2016-08-15T20:28:32.993 回答