トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

10-185 範囲内での行間アクセス(歯抜けを考慮しない)

SQLパズル

ValTable
Seq  Val
---  ---
  1  111
  2  222
  3  333
  4  444
  5  555
  6  666

連続しているSeqの
2から5のレコードのValを以下の形で
行間アクセスして求める。
(2から5でないレコードのValは、そのまま)

Seqが2のレコードは、Seqが3のレコードのVal(333)がNewVal
Seqが3のレコードは、Seqが4のレコードのVal(444)がNewVal
Seqが4のレコードは、Seqが5のレコードのVal(555)がNewVal
Seqが5のレコードは、Seqが2のレコードのVal(222)がNewVal

出力結果
Seq  Val  NewVal
---  ---  ------
  1  111     111
  2  222     333
  3  333     444
  4  444     555
  5  555     222
  6  666     666

こちらを参考にさせていただきました(英語)


データ作成スクリプト

create table ValTable as
select 1 as Seq, 111 as Val from dual
union select 2,222 from dual
union select 3,333 from dual
union select 4,444 from dual
union select 5,555 from dual
union select 6,666 from dual;


SQL

--■■■分析関数を使う方法■■■
select seq,val,
case when seq = 5
     then Lag(Val,5-2) over(order by seq)
     when seq between 2 and 5
     then Lead(Val,1) over(order by seq)
else Val end as NewVal
from ValTable
order by Val;

--■■■model句を使う方法(10g以降)■■■
select Seq,Val,NewVal
  from ValTable
 model
 dimension by (Seq)
 measures(Val,Val as NewVal)
 rules(NewVal[2] = Val[3],
       NewVal[3] = Val[4],
       NewVal[4] = Val[5],
       NewVal[5] = Val[2])
order by Seq;


解説

Seqの歯抜けを考慮しなくていいのであれば、
Lag関数やLead関数が使えます。