2017-01-12 18 views
2

に参加減算値は、私は次のような問題を持っている

id,  timestamp, value1,value2,value3 
1, 12.01.2017 09:00:01, 234, 345, 456 
2, 12.01.2017 09:00:05, 567, 678, 789 
3, 12.01.2017 09:00:25, 777, 888, 999 

値はABSOLUT値です。今私は新しいテーブルにこのデータを挿入する必要がありますが、増分値として。 これは、各レコードの前のレコードを見つけて値を減算する必要があることを意味します。
残念ながらイムが届かない... 私はこのような自己結合を試してみました:

select 
    se1.timestamp, 
    se1.value1, 
    se1.value2, 
    se1.value3 
from 
    table1 se1, 
    table1 se2 
where 
    se1.id = se2.id 
    and se1.timestamp < (select max(timestamp) from table1) 
order by 
    timestamp desc 
fetch first 100 rows only; 

誰もこれで私を助けることができれば、それは素晴らしいことだ...

出力になるはずですこのように:

timestamp,   value1, value2, value3 
12.01.2017 09:00:05, 333, 333, 333 (record from 09:00:01 subtracted) 
12.01.2017 09:00:25, 210, 210, 210 (record from 09:00:05 subtracted) 

私は、誰もがこれを理解することを願っ;)

+0

Ops。私はコードをフォーマットするのを忘れました: – Monument

+1

私はあなたの質問を得ることができません、あなたは希望の出力の例を提供できますか? –

+0

質問を簡単に編集してコードとデータをフォーマットすることができます(ヒント:ctrl + k) – Aleksej

答えて

2

私はよく理解している場合は、 timestampで順序付けられた、現在の行の値と前の行の値との差を計算する必要があります(value1value2およびvalue3)。

with test(id,  timestamp, value1, value2, value3) as ( 
    select 1, to_timestamp('12.01.2017 09:00:01', 'dd.mm.yyyy hh24:mi:ss'), 234, 345, 456 from dual union all 
    select 2, to_timestamp('12.01.2017 09:00:05', 'dd.mm.yyyy hh24:mi:ss'), 567, 678, 789 from dual union all 
    select 3, to_timestamp('12.01.2017 09:00:25', 'dd.mm.yyyy hh24:mi:ss'), 777, 888, 999 from dual 
) 
select timestamp, 
     value1 - lag(value1, 1, 0) over (order by timestamp) increment1, 
     value2 - lag(value2, 1, 0) over (order by timestamp) increment2, 
     value3 - lag(value3, 1, 0) over (order by timestamp) increment3 
from test 

をこれは、このように与えて、前の行を評価し、現在の行の値との違いを確認するためにLAGを使用しています:もしそうなら、あなたが必要になることがあり timestampであることを

TIMESTAMP      INCREMENT1 INCREMENT2 INCREMENT3 
12/01/2017 09:00:01,000000000 234   345   456 
12/01/2017 09:00:05,000000000 333   333   333 
12/01/2017 09:00:25,000000000 210   210   210 

お知らせOracle型であるため、列の名前として使用しない方が良いでしょう。

また、Boneistのコメントに気づく:私の答えの最初のバージョンでは、私はLAG(..)nullある場合(最初の行)を処理するためにNVL(LAG(..), 0)のようなものを使用。 Boneistのコメントでは、必要な先行行が存在しない場合にはLAGが既定値を処理しているので、NVLを避けることができます。

+1

ここにNVLは必要ありません。ヌルを処理するために、['LAG()'](https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions082.htm#SQLRF00652)の追加パラメータを使用することができます。 'LAG(value1,1,0)OVER ...' – Boneist

+1

@Boneistいつも何かを学ぶ..ありがとう – Aleksej

+0

@Boneist部分編集、申し訳ありません – Aleksej

関連する問題