トップページに戻る
次のmodel句のサンプルへ
前のmodel句のサンプルへ
model句20 rules句で、case式で場合分け
SQLパズル
Seq Flag
--- ----
1 AAAA ←出力対象
2 AAAA ←出力対象
3 BBBB ←出力対象
4 BBBB ←出力対象
5 CCCC ←出力対象
6 AAAA ←出力対象
7 BBBB ←出力対象
8 CCCC ←出力対象
9 AAAA ←出力対象
10 AAAA ←出力対象
11 CCCC ←出力対象
12 CCCC
13 BBBB
14 AAAA ←出力対象
15 AAAA ←出力対象
16 BBBB ←出力対象
17 CCCC ←出力対象
18 BBBB
Seqの昇順で、
AAAAの行から、CCCCの行まで出力する。ことを繰り返す。
出力結果
Seq Flag
--- ----
1 AAAA
2 AAAA
3 BBBB
4 BBBB
5 CCCC
6 AAAA
7 BBBB
8 CCCC
9 AAAA
10 AAAA
11 CCCC
14 AAAA
15 AAAA
16 BBBB
17 CCCC
データ作成スクリプト
create table SeqTable(ID,Flag) as
select 1,'AAAA' from dual union
select 2,'AAAA' from dual union
select 3,'BBBB' from dual union
select 4,'BBBB' from dual union
select 5,'CCCC' from dual union
select 6,'AAAA' from dual union
select 7,'BBBB' from dual union
select 8,'CCCC' from dual union
select 9,'AAAA' from dual union
select 10,'AAAA' from dual union
select 11,'CCCC' from dual union
select 12,'CCCC' from dual union
select 13,'BBBB' from dual union
select 14,'AAAA' from dual union
select 15,'AAAA' from dual union
select 16,'BBBB' from dual union
select 17,'CCCC' from dual union
select 18,'BBBB' from dual;
SQL
--■■■model句を使う方法(10g以降)■■■
select ID,Flag
from (select ID,Flag,willOut
from SeqTable
model
dimension by(ID)
measures(Flag,0 as willOut)
rules(
willOut[ID] order by ID =
case when Flag[cv()] = 'AAAA' then 1
when presentv(Flag[cv()-1],1,0) = 0 then 0
when Flag[cv()-1] = 'CCCC' then 0
else willOut[cv()-1] end))
where willOut = 1;
--■■■表関数を使う方法■■■
create or replace package packModel20 Is
type PrintType is record(
ID SeqTable.ID%type,
Flag SeqTable.Flag%type);
type PrintTypeSet is table of PrintType;
end;
/
create or replace function PrintRecord return packModel20.PrintTypeSet PipeLined IS
out_rec packModel20.PrintType;
willOut boolean := false;
begin
for rec in (select ID,Flag
from SeqTable
order by ID) Loop
if rec.Flag = 'AAAA' then
willOut := true;
end if;
if willOut then
out_rec.ID := rec.ID;
out_rec.Flag := rec.Flag;
pipe row(out_rec);
end if;
if rec.Flag = 'CCCC' then
willOut := false;
end if;
end loop;
end;
/
sho err
select ID,Flag from table(PrintRecord);
解説
@IT会議室のアレンジ問題です。
model句を使う方法では、case式で場合分けのロジックを使ってます。
なぜ場合分けが必要か
表関数を使うのもいいでしょう。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
10.2.0.1.0でcase式で、not is presentを使ったら、
ORA-03113: が出ました・・・
"case when not m[1] is present then" outputs ORA-03113
select * from dual model
dimension by(0 as d)
measures(1 as m)
rules(
m[any] = case when not m[1] is present then 3 end);
ORA-03113: 通信チャネルでend-of-fileが検出されました
なので、presentvで代用するといいでしょう。
select * from dual model
dimension by(0 as d)
measures(1 as m)
rules(
m[any] = case when presentv(m[1],1,0) = 0 then 3 end);
D M
- -
0 3