はじめに
前バージョンのOracle 10gから新機能として導入されたPartitioned Outer Join
について、基本事項から使用例まで、SQLのイメージを交えて解説します。
Partitioned Outer Join
の便利さを実感しやすくするために、CodeZine Booksの『達人に学ぶ SQL徹底指南書』で扱われている問題をPartitioned Outer Join
を使って解くことも試みます。
対象読者
- Oracleの
Partitioned Outer Join
を使いたい方 - OracleのSQLの理解を深めたい方
必要な環境
本稿で扱うSQLは、Oracle 11.2.0.1.0で動作確認しました。
1. Partitioned Outer Joinとは
Partitioned Outer Join
は、Oracle 10g R1の新機能で、パーティションを切ってできた各集合と外部結合させることができます。Partitioned Outer Join
は、パーティション化された外部結合とも呼ばれます。
Partitioned Outer Join
には、左外部結合(Left Outer Join
)で使われるPartitioned Outer Join
と、右外部結合(Right Outer Join
)で使われるPartitioned Outer Join
がありますが、本稿では前者のみを扱います。
2. Partitioned Outer Joinの基本的な使用例
まずは、Partitioned Outer Join
の基本的な使用例について見てみます。サンプルを見てみましょう。
Key |
10 |
20 |
30 |
40 |
ID | Key | Name |
AAAA | 10 | aaaa |
AAAA | 20 | bbbb |
BBBB | 10 | cccc |
CCCC | 10 | dddd |
CCCC | 30 | eeee |
TranTableでIDごとに、MasterTableに存在しないKeyを補完します。例えば、ID=AAAAの集合には、Key=30の行とKey=40の行が存在しませんので、Key=30の行とKey=40の行が補完されます。なお、補完された行のName列はNULLとします。
ID | Key | Name |
AAAA | 10 | aaaa |
AAAA | 20 | bbbb |
AAAA | 30 | null |
AAAA | 40 | null |
BBBB | 10 | cccc |
BBBB | 20 | null |
BBBB | 30 | null |
BBBB | 40 | null |
CCCC | 10 | dddd |
CCCC | 20 | null |
CCCC | 30 | eeee |
CCCC | 40 | null |
このように、集合ごとにマスタ側に存在しなければ行を補完する、といった要件でPartitioned Outer Join
は特に効果を発揮します。Partitioned Outer Join
を使って上記の出力結果を取得するSQLを見てみましょう。
select b.ID,a.Key,b.Name from MasterTable a Left Join TranTable b partition by (b.ID) on a.Key = b.Key order by b.ID,a.Key;
Partitioned Outer Join
は、Left
を残す形で、Partitioned
(パーテションを切られた)Outer
(外部の集合)をJoin
(結合)させる。と覚えるといいでしょう。
SQLのイメージは、下のようになります。partition by (b.ID)
ですので、b.ID
ごとに区切る赤線をイメージし、左外部結合(Left Join
)のベン図もイメージして、それぞれの左外部結合の結果がunion all
されると理解すると分かりやすいでしょう。
単なるLeft Joinとの違い
なお、Partitioned Outer Join
ではなく、下記のような単なるLeft Join
だと違う出力結果となります。
select b.ID,a.Key,b.Name from MasterTable a Left Join TranTable b on a.Key = b.Key order by b.ID,a.Key;
ID | Key | Name |
AAAA | 10 | aaaa |
AAAA | 20 | bbbb |
BBBB | 10 | cccc |
CCCC | 10 | dddd |
CCCC | 30 | eeee |
null | 40 | null |
Partitioned Outer Joinの代用法
ちなみに、下記のSQLのようにクロスジョインと外部結合を組み合わせて、Partitioned Outer Join
と同じ結果を取得することもできますが、Partitioned Outer Join
を使ったほうがシンプルだと思います。
select a.ID,b.Key,c.Name from (select distinct ID from TranTable) a cross Join (select Key from MasterTable) b Left Join TranTable c on a.ID = c.ID and b.Key = c.Key order by a.ID,b.Key;