-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 の大きな intですtime * 1000

マシンが実行されている場合、このデータは ~30 秒 (30,000) ごとにログに記録されます。前の行から 2 分 (120,000) 未満である場合、時間差の合計を照会しようとしています。2 分を超える場合は、マシンがオフになっていて、その行が次の合計の新しい開始時間になると思います。

ここでの私の目標は、タイム スタンプを使用して合計実行時間の合計を取得することです。

私はこれをどこから始めるべきか完全に途方に暮れています。私はこの説明を私にとって意味のあるものにするのに苦労しました.

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;

これは、「ギャップと島」の見出しの下にあるかなり典型的な問題です。あなたの質問に似た例がたくさん見つかります。

偶然にも、10 年以上前のこの 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 に答える