2

我被困在使用分区实现 LEAD/LAG 的问题上。

以下是示例和预期结果

create table trd(
     key number,
     book number,
     prd_key number,
     direction varchar2(2),
     trdtime date,
     price number)




insert into trd values(1234,115,133864,'B','17-07-2013 18:18:00',108.859);
insert into trd values(1235,115,133864,'S','17-07-2013 18:18:00',108.859);
insert into trd values(1245,115,133864,'S','17-07-2013 18:18:00',108.859);
insert into trd values(1236,115,133864,'B','15-07-2013 18:18:00',108.872);
insert into trd values(1237,115,133864,'S','15-07-2013 18:18:00',108.866);
insert into trd values(1247,115,133864,'S','15-07-2013 18:18:00',108.866);
insert into trd values(1238,115,133864,'S','14-07-2013 18:18:00',107.86);
insert into trd values(1239,115,133864,'S','14-07-2013 18:17:00',108.86);
insert into trd values(1240,115,133864,'B','14-07-2013 18:12:00',109.86);
insert into trd values(1241,115,133864,'B','14-07-2013 18:17:00',110.86);

我需要返回这样的值:

Key    Book    Prd_Key Dir  TrdTime             Price       NextPrice
1234    115    133864    B  7/17/2013 6:18:00 PM   108.859  108.866
1235    115    133864    S  7/17/2013 6:18:00 PM   108.859  108.872
1245    115    133864    S  7/17/2013 6:18:00 PM   108.859  108.872
1236    115    133864    B  7/15/2013 6:18:00 PM   108.872  108.86
1237    115    133864    S  7/15/2013 6:18:00 PM   108.866  110.86
1247    115    133864    S  7/15/2013 6:18:00 PM   108.866  110.86
1238    115    133864    S  7/14/2013 6:18:00 PM   107.86   110.86
1239    115    133864    S  7/14/2013 6:17:00 PM   108.86   109.86
1240    115    133864    B  7/14/2013 6:12:00 PM   109.86   NULL
1241    115    133864    B  7/14/2013 6:17:00 PM   110.86   NULL

嵌入的逻辑是:

对于每条记录,需要获取相反方向的和现有TrdTime > 其他记录TrdTime。例如:对于键 1237,Direction 是 S,TrdTime 是 7/15/2013 6:18:00 PM。此记录返回以下记录:1240 和 1241 都具有对侧“B”和现有记录 TrdTime > 这两个记录。但是选择了 1241 的 TrdTime,因为它是按最近和最高的 TrdTime 排序的。

我怎样才能实现这个功能。

我正在考虑使用 LEAD 函数和分区来完成它。

我不能使用游标,因为表没有索引并且有超过 5 百万条记录。我不想自己加入,因为这非常耗时。

请有任何建议。

4

1 回答 1

1

作为其中一种方法,我们可以执行以下操作:

with cte(key, book, prd_key, direction, trdtime, price, grp) as(
  select t.*
      , dense_rank() over(order by t.trdtime desc)
    from trd t
)
select q.key
     , q.book
     , q.prd_key
     , q.direction
     , q.trdtime
     , q.price
     , grp
     , (select max(c.price)
           from cte c
          where q.direction <> c.direction
            and c.grp = (select min(grp) 
                          from cte l 
                         where l.direction <> q.direction 
                           and l.grp > q.grp
                         )
        ) as next_price
  from cte q

结果:

Key   Book   Prd_Key  Direction  Trdtime              Price    Next_Price 
----------------------------------------------------------------------------
1234  115    133864   B          17.07.13 6:18:00 PM  108,859  108,866 
1235  115    133864   S          17.07.13 6:18:00 PM  108,859  108,872 
1245  115    133864   S          17.07.13 6:18:00 PM  108,859  108,872 
1236  115    133864   B          15.07.13 6:18:00 PM  108,872  107,86 
1237  115    133864   S          15.07.13 6:18:00 PM  108,866  110,86 
1247  115    133864   S          15.07.13 6:18:00 PM  108,866  110,86 
1238  115    133864   S          14.07.13 6:18:00 PM  107,86   110,86 
1239  115    133864   S          14.07.13 6:17:00 PM  108,86   109,86 
1241  115    133864   B          14.07.13 6:17:00 PM  110,86   null 
1240  115    133864   B          14.07.13 6:12:00 PM  109,86   null

SQLFiddle 演示

dens_rank()使用解析函数将记录分组:

  select t.*
       , dense_rank() over(order by t.trdtime desc)
    from trd t

结果:

Key   Book   Prd_Key  Direction  Trdtime              Price    Next_Price  grp
----------------------------------------------------------------------------
1234  115    133864   B          17.07.13 6:18:00 PM  108,859  108,866     1
1235  115    133864   S          17.07.13 6:18:00 PM  108,859  108,872     1
1245  115    133864   S          17.07.13 6:18:00 PM  108,859  108,872     1
1236  115    133864   B          15.07.13 6:18:00 PM  108,872  107,86      2
1237  115    133864   S          15.07.13 6:18:00 PM  108,866  110,86      2
1247  115    133864   S          15.07.13 6:18:00 PM  108,866  110,86      2
1238  115    133864   S          14.07.13 6:18:00 PM  107,86   110,86      3
1239  115    133864   S          14.07.13 6:17:00 PM  108,86   109,86      4
1241  115    133864   B          14.07.13 6:17:00 PM  110,86   null        4
1240  115    133864   B          14.07.13 6:12:00 PM  109,86   null        5

然后我们选择Next_price一个max(price)最近的组,其中包括相反的方向。

于 2013-08-28T17:32:48.263 回答