トップページに戻る
次のSQLパズルへ
前のSQLパズルへ
7-70 クロスジョインして分析関数
SQLパズル
UserLogテーブル
UserID SyouhinID
------ ---------
ID0001 AAA
ID0001 BBB
ID0001 CCC
ID0002 AAA
ID0003 AAA
ID0003 DDD
ID0004 EEE
SyouhinMasterテーブル
SyouhinID Val
--------- ---
AAA 001
BBB 002
CCC 003
DDD 004
EEE 005
UserLogテーブルのUserIDごとに
SyouhinMasterテーブルの、
SyouhinIDのデータを持てば1、持たなければ0を
Flagとして以下の形式で出力する
出力結果
UserID Val Flag
------ --- ----
ID0001 001 1
ID0001 002 1
ID0001 003 1
ID0001 004 0
ID0001 005 0
ID0002 001 1
ID0002 002 0
ID0002 003 0
ID0002 004 0
ID0002 005 0
ID0003 001 1
ID0003 002 0
ID0003 003 0
ID0003 004 1
ID0003 005 0
ID0004 001 0
ID0004 002 0
ID0004 003 0
ID0004 004 0
ID0004 005 1
データ作成スクリプト
create table UserLog as
select 'ID0001' as UserID,'AAA' as SyouhinID from dual
union select 'ID0001','BBB' from dual
union select 'ID0001','CCC' from dual
union select 'ID0002','AAA' from dual
union select 'ID0003','AAA' from dual
union select 'ID0003','DDD' from dual
union select 'ID0004','EEE' from dual;
create table SyouhinMaster as
select 'AAA' as SyouhinID,'001' as Val from dual
union select 'BBB','002' from dual
union select 'CCC','003' from dual
union select 'DDD','004' from dual
union select 'EEE','005' from dual;
SQL
--■■■分析関数を使う方法■■■
select distinct a.UserID,b.Val,
sum(decode(a.SyouhinID,b.SyouhinID,1,0)) over(partition by a.UserID,b.Val) as Flag
from UserLog a,SyouhinMaster b
order by UserID,Val;
--■■■グループ化する方法■■■
select a.UserID,b.Val,
sum(decode(a.SyouhinID,b.SyouhinID,1,0)) as Flag
from UserLog a,SyouhinMaster b
group by a.UserID,b.Val
order by a.UserID,b.Val;
--■■■SQL99の結合構文を使う方法■■■
select c.UserID,b.Val,nvl2(a.SyouhinID,1,0) as Flag
from SyouhinMaster b cross join (select distinct UserID from UserLog) c
Left Join UserLog a
on a.UserID = c.UserID
and a.SyouhinID = b.SyouhinID
order by c.UserID,b.Val;
--■■■Partitioned Outer Joinを使う方法(10g以降)■■■
select b.UserID,a.Val,nvl2(b.SyouhinID,1,0) as Flag
from SyouhinMaster a
Left Join UserLog b
partition by (b.UserID)
on (a.SyouhinID = b.SyouhinID)
order by b.UserID,a.Val;
解説
パフォーマンスの上では、
表に二回アクセスするのを避けるか
クロスジョインを避けるか
になりますね
10g以降なら、Partitioned Outer Joinを使ってもいいでしょう。
3-34 Partitioned Outer Join