トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-101 直前の値と等しかったら削除
SQLパズル
ABCTable
ColA ColB ColC
---- ---- ----
101 1 10
103 1 10 ←削除対象
105 1 11
106 1 11 ←削除対象
108 1 10
102 2 11
104 2 11 ←削除対象
107 2 12
109 2 12 ←削除対象
order by ColB,ColA
でソートした時に、
直前のレコードとColCが等しいレコードを削除する。
データ作成スクリプト
create Table ABCTable(
ColA number(3),
ColB number(1),
ColC number(2),
primary key(ColA));
insert into ABCTable values(101,1,10);
insert into ABCTable values(103,1,10);
insert into ABCTable values(105,1,11);
insert into ABCTable values(106,1,11);
insert into ABCTable values(108,1,10);
insert into ABCTable values(102,2,11);
insert into ABCTable values(104,2,11);
insert into ABCTable values(107,2,12);
insert into ABCTable values(109,2,12);
commit;
SQL
--■■■分析関数を使わない方法■■■
delete from ABCTable a
where ColC = (select b.ColC
from (select c.ColA,c.ColB,c.ColC
from ABCTable c
order by c.ColB desc,c.ColA desc) b
where (b.ColB < a.ColB
or (b.ColB = a.ColB and b.ColA < a.ColA))
and RowNum = 1);
--■■■分析関数を使う方法■■■
delete from ABCTable
where RowID in (select Row_ID
from (select ColC,RowID as Row_ID,
Lag(ColC) over(order by ColB,ColA) as LagColC
from ABCTable)
where ColC = LagColC);
--■■■複数列in述語を使う方法■■■
delete from ABCTable
where (RowID,ColC)
in (select RowID,Lag(ColC) over(order by ColB,ColA)
from ABCTable);
解説
分析関数を使わない方法では、
インラインビューで
order by ColB,ColA
のascとdescを入れ替えた逆ソートを行って、
RowNum=1を指定して直前の値を取得してます。