トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
10-102 ログテーブルの循環使用
SQLパズル
ログ履歴テーブル 当日ログテーブル
Seq LogTxt Seq LogTxt
--- --------- --- ---------
2 ログ履歴1 16 当日ログ1
4 ログ履歴2 18 当日ログ2
6 ログ履歴3 20 当日ログ3
8 ログ履歴4 22 当日ログ4
10 ログ履歴5 24 当日ログ5
12 ログ履歴6
14 ログ履歴7
当日ログテーブルのデータを、
ログ履歴テーブルに移し変える、
ただし、ログ履歴テーブルのデータは最大10件として、
10件を超えたらSeqが古いデータから上書きする。
更新結果
Seq LogTxt
--- ---------
6 ログ履歴3
8 ログ履歴4
10 ログ履歴5
12 ログ履歴6
14 ログ履歴7
16 当日ログ1
18 当日ログ2
20 当日ログ3
22 当日ログ4
24 当日ログ5
データ作成スクリプト
create table ログ履歴(
Seq number(4),
LogTxt varchar2(20));
insert into ログ履歴
select RowNum*2,'ログ履歴' || to_char(RowNum)
from all_catalog
where RowNum <= 7;
create table 当日ログ
as select * from ログ履歴
where RowNum = 0;
insert into 当日ログ
select RowNum*2+14,'当日ログ' || to_char(RowNum)
from all_catalog
where RowNum <= 5;
commit;
SQL
merge into ログ履歴 a
using(select Seq,LogTxt,Row_Number() over(order by Seq) as Rank
from 当日ログ) b
on ((select count(*)+1
from ログ履歴 c
where c.Seq < a.Seq) = b.Rank + (select count(*) from ログ履歴) - 10)
when matched then
update set a.Seq= b.Seq,a.LogTxt=b.LogTxt
when not matched then
insert(a.Seq,a.LogTxt) values(b.Seq,b.LogTxt);
解説
on句で、
相関サブクエリで、順位を求めてます。
当日ログテーブルが11件以上のレコードを持つ場合は、
using句で、Seqの上位10件を抽出しておけばいいでしょう。