我有以下问题:
表1:
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
值是绝对值。现在我需要将此数据插入到新表中,但作为增量值。 这意味着我必须找到每条记录的先前记录并减去这些值 但不幸的是我没有到达那里...... 我尝试过像这样的自我加入:
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 :(得分:2)
如果我理解得很清楚,您需要计算每个值(value1
,value2
和value3
)当前行中的值与前一行中的值之间的差异,由timestamp
排序。
如果是这样,您可能需要:
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 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
请注意,timestamp
是Oracle类型,因此最好不要将其用作列的名称。
另外,请注意Boneist的评论:在我的回答的第一个版本中,我使用类似NVL(LAG(..), 0)
的内容来处理LAG(..)
为null
(第一行)的情况。 Boneist的评论让我注意到LAG
已经处理了一个默认值,以防所需的前一行不存在,从而允许我避开NVL
。