我有一个像这样的查询。
select m.*, lag (kod) over (partition by drv order by rn) from m;
DRV列只有两个可能的值。查询显然会返回"滞后"与当前行相同的drv-group的值。
但是,我需要选择KOD列的值,该列的最大可能RN小于当前行的RN,DRV 不等于当前行的DRV。显然我可以写一个相关的子查询,但我正在寻找更高效的东西。
非常感谢任何建议。
修改
正如评论中所提到的,一些样本数据会使问题更加清晰。
RN DRV KOD LAG(KOD)
1365 lf 115892 115786
1366 zon 1159 1158
1367 lf 115927 115892
1368 zon 116 1159
1369 zon 1160 116
1370 lf 116029 115927
1371 lf 116043 116029
这是上面给出的查询的结果。我只对DRV =' lf'的记录感兴趣。例如,对于RN = 1367,我们有LAG(KOD)= 115892,因为这是该组中的先前记录。我不需要从同一个分区/组中获取先前的记录,而是需要一个查询,该查询将从另一个组返回先前的记录 - 在RN = 1367的情况下,它必须返回1159.这是因为对于有问题的记录DRV = ' LF'所以我想在另一个分区中查找KOD,这是DRV =' zon'并且由RN选择LAG超过订单,这是RN = 1366的记录。 因此,规则必须如下:
RN DRV KOD NEW_LAG(KOD)
1365 lf 115892 ?
1366 zon 1159 ?
1367 lf 115927 1159
1368 zon 116 ?
1369 zon 1160 ?
1370 lf 116029 1160
1371 lf 116043 1160
请注意,我对DRV =' zon'的记录结果不感兴趣。这就是为什么我在那里写了一个问号。
答案 0 :(得分:1)
LAST_VALUE IGNORE NULL为你完成工作
with dat as (
select 1365 RN , 'lf' DRV, 115892 KOD from dual union all
select 1366 RN , 'zon' DRV, 1159 KOD from dual union all
select 1367 RN , 'lf' DRV, 115927 KOD from dual union all
select 1368 RN , 'zon' DRV,116 KOD from dual union all
select 1369 RN , 'zon' DRV, 1160 KOD from dual union all
select 1370 RN , 'lf' DRV, 116029 KOD from dual union all
select 1371 RN , 'lf' DRV, 116043 KOD from dual),
dat2 as (
select
RN, DRV, KOD,
LAST_VALUE(case when DRV = 'zon' then KOD end IGNORE NULLS) over ( order by RN) as LAG_KOD_ZON,
lag(KOD) over (order by RN) as LAG_KOD
from dat
)
select
RN, DRV, KOD,
CASE WHEN DRV = 'lf' THEN LAG_KOD_ZON end as LAG_KOD
from dat2;
结果
RN DRV KOD LAG_KOD
---------- --- ---------- ----------
1365 lf 115892
1366 zon 1159
1367 lf 115927 1159
1368 zon 116
1369 zon 1160
1370 lf 116029 1160
1371 lf 116043 1160