其他组的分析函数LAG

时间:2016-01-14 17:12:12

标签: sql oracle window-functions

我有一个像这样的查询。

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'的记录结果不感兴趣。这就是为什么我在那里写了一个问号。

1 个答案:

答案 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