如何查询 SQL 服务器数据库以获得时差总和,但前提是它们相差小于 2 分钟

How to query SQL Server database to get a sum of time differences but only if they are less than 2 min different

我有以下查询数据是:

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 的 big int time * 1000

如果机器 运行ning,则此数据每 ~30 秒 (30,000) 记录一次。我试图查询这个时间差的总和,如果它们距离它前面的行不到两分钟(120,000)。如果它超过两分钟,那么我假设机器已关闭并且该行将是下一个总和的新开始时间。

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

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

如果您没有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;

这是 "Gaps and Islands" 标题下的一个相当典型的问题。你会发现很多与你的问题相似的例子。

今天我偶然发现了这个 Oracle article 十多年前的东西。它使用了一种您可能会感兴趣的略有不同的方法。

编辑:

这里是逻辑的快速分解。

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

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

试试 cursor.

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