2. intersect
intersectは、積集合演算を行います。MySQLで同じ結果を取得してみましょう。まずは、テーブルのデータ(前問と同じ)と、出力結果を考えます。
| PKey | Val |
| 1 | 2 |
| 2 | null |
| 3 | null |
| 4 | 8 |
| PKey | Val |
| 1 | 2 |
| 2 | null |
| 3 | 5 |
| 4 | 9 |
TBL1に存在して、TBL2にも存在する行を出力します。言いかえれば、Oracleの下記のintersectを使ったSQLと同じ結果を取得します。
select PKey,Val from TBL1 intersect select PKey,Val from TBL2;
| PKey | Val |
| 1 | 2 |
| 2 | null |
場合によっては、下記のような自然結合が使えるのですが、集合演算は、null同士を等しいと判定するのに対して、自然結合は、null同士を等しいと判定しないので、この場合は、自然結合で正しい結果を取得できません。
select PKey,Val from TBL1 NATURAL JOIN TBL2;
| PKey | Val |
| 1 | 2 |
前問と似た考え方で、TBL1に存在して、TBL2にも存在する行を出力するので、exists述語を使えばいいと考え、答えは下記となります。
select PKey,Val
from TBL1 a
where exists(select 1 from TBL2 b
where b.PKey <=> a.PKey
and b.Val <=> a.Val);
exists述語を使う方法の、SQLのイメージは下記です。

別の考え方として、下記のようにunion allとgroup byを使う方法もあります。
select PKey,Val
from (select PKey,Val from TBL1 union all
select PKey,Val from TBL2) a
group by PKey,Val
having count(*) = 2;
union allとgroup byを使う方法の、SQLのイメージは下記です。

3. 完全外部結合
左外部結合と右外部結合の和集合を取得する完全外部結合は、Oracle9iから使用可能になりました。MySQLで同じ結果を取得してみましょう。まずは、テーブルのデータと、出力結果を考えます。
| PKey | Val |
| 1 | aaa |
| 2 | bbb |
| PKey | Val |
| 1 | ccc |
| 3 | ddd |
Oracleの下記の完全外部結合を使ったSQLと同じ結果を取得します。
select a.PKey as aPKey,a.Val as aVal,
b.PKey as bPKey,b.Val as bVal
from FJoin1 a full join FJoin2 b
on (a.PKey=b.PKey)
order by nvl(a.PKey,b.PKey);
| aPKey | aVal | bPKey | bVal |
| 1 | aaa | 1 | ccc |
| 2 | bbb | null | null |
| null | null | 3 | ddd |
完全外部結合は、左外部結合と右外部結合の和集合を取得することに注目して、答えは、下記となります。
select a.PKey as aPKey,a.Val as aVal,
b.PKey as bPKey,b.Val as bVal
from FJoin1 a Left Join FJoin2 b
on (a.PKey=b.PKey)
union
select a.PKey as aPKey,a.Val as aVal,
b.PKey as bPKey,b.Val as bVal
from FJoin1 a right Join FJoin2 b
on (a.PKey=b.PKey);
外部結合を使う方法の、SQLのイメージは下記です。

別の考え方として、下記のようにunion allとgroup byを使う方法もあります。
select max(case ID when 1 then PKey end) as aPKey,
max(case ID when 1 then Val end) as aVal,
max(case ID when 2 then PKey end) as bPKey,
max(case ID when 2 then Val end) as bVal
from (select 1 as ID,PKey,Val from FJoin1 union all
select 2 as ID,PKey,Val from FJoin2) d
group by PKey;
union allとgroup byを使う方法の、SQLのイメージは下記です。

