2013-08-28 27 views
2

我被一個問題困在實施LEAD/LAG分區的問題上。在Oracle中使用鉛的分區

下面是

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 

嵌入邏輯是:

對於每個記錄,極品獲取OPPOSITE方向和現有的TrdTime>其他記錄TrdTime。 例如:對於鍵1237,方向是S並且TrdTime是7/15/2013 6:18:00 PM。 此記錄返回以下記錄: 1240和1241都有對面'B'和現有記錄TrdTime>這兩個記錄。 但是由於它是按最近的和最高的TrdTime排序的,因此選擇了1241的TrdTime。

如何實現此功能。

我正在考慮使用LEAD函數和分區。

我不能使用遊標,因爲表格沒有編制索引並且有超過5密爾的記錄。 我不想做自我加入或者sicne它非常耗時。

請提出任何建議。

+0

'trdtime = 7/14/2013 6:12:00 PM'如何在'trdtime = 7/14/2013 6:17:00'兩個記錄之間結束? 'trdtime = 7/14/2013 6:12:00 PM'的記錄不應該是最後一個,根據「最近和最高的TrdTime排序」?或者還有另一個你沒有提到的訂購規則? –

+0

沒有額外的訂購。 trdtime = 7/14/2013 6:12:00 PM的記錄最後可能會出現。忽略訂單。 – cormalado

回答

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 Demo

的記錄分爲使用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)

+0

難以置信你可以用sql做什麼,呵? :)雖然個人的可維護性,我可能會使用PL/SQL這個複雜的東西。 ;)噢,也許你應該解釋一下,通過使用,你實際上只查詢表「trd」一次。 – winkbrace