トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-239 Last_Value(式 ignore nulls)でupdate
SQLパズル
TBL_A
ID 計算値 条件A 条件B
-- ------ ----- -----
1 100 101 102
2 null 80 50
3 null 120 130
4 null 70 200
5 null 999 111
6 null 333 444
7 null 100 500
update文で、
「計算値」列に、
条件A - 条件B が負数ならば、1つ上のIDの「計算値」列を
負数でなければ、条件A - 条件B
をセットする。
更新結果
ID 計算値 条件A 条件B
-- ------ ----- -----
1 100 101 102
2 null 80 50
3 null 120 130
4 null 70 200
5 888 999 111
6 888 333 444
7 888 100 500
データ作成スクリプト
create table TBL_A(ID primary key,計算値,条件A,条件B) as
select 1,100 ,101,102 from dual union
select 2,null, 80, 50 from dual union
select 3,null,120,130 from dual union
select 4,null, 70,200 from dual union
select 5,null,999,111 from dual union
select 6,null,333,444 from dual union
select 7,null,100,500 from dual;
SQL
--■■■ignore nullsを使わない方法■■■
update TBL_A a
set 計算値 = (select set計算値
from (select Row_ID,
max(decode(ID,RefID,set計算値))
over(partition by RefID) as set計算値
from (select ID,RowID as Row_ID,
case when ID=1 then 計算値
else 条件A - 条件B end as set計算値,
max(case when ID=1 or 条件A - 条件B >= 0
then ID end) over(order by ID) as RefID
from TBL_A)) bbb
where bbb.Row_ID = a.RowID)
where ID > 1;
--■■■ignore nullsを使う方法(10g以降)■■■
update TBL_A a
set 計算値 = (select set計算値
from (select RowID as Row_ID,
Last_value(case when ID=1 or 条件A - 条件B >= 0
then 条件A - 条件B end ignore nulls)
over(order by ID) as set計算値
from TBL_A) b
where b.Row_ID = a.RowID)
where ID > 1;
解説
分析関数の結果でupdateするのは、DB2なら楽にできたりします。
(DB2のLast_Valueでignore nullsが使えるか分かりませんが)
10gのLast_value(式 ignore nulls)を9iで模倣する議論
Carry Forward