ray88’s diary

お仕事で困ったとき用の自分用の覚書

SQL指南書 外部結合⑥ 完全外部結合

SQL 指南書集 目次 - ray88’s diary
SQLでは以下3種類の外部結合の構文が定義されている
1.左外部結合(LEFT OUTER JOIN)
2.右外部結合(RIGHT OUTER JOIN)
3.完全外部結合(FULL OUTER JOIN)

※左外部結合と右外部結合に機能的な差はない
 マスタに使うテーブルを演算子の左に書けば左外部結合、右に書けば右外部結合を使用する

完全外部結合:両方をマスタに使う結合
 データ内容が不一致の2つのテーブルから、情報を欠落させずに結果を得るための方法
 ※完全会部結合の「完全」とは情報を「完全に保存する」という意味
集合演算の視点で見る結合
 内部結合:積集合(INTERSECT「交差」とも呼ぶ)

 外部結合:和集合(UNION)
     ※情報を落とさない、という意味でUNIONやMERGEは外部結合とよく似ている

例題
クラスAに所属する生徒のテーブル「Class_A」とクラスBに所属する生徒のテーブル「Class_B」を結合し、
両方の生徒全員を表示させる
※田中、鈴木の2人は両方のテーブルに存在し、伊集院と西園寺は片方のテーブルにしか存在しない。


【解答SQL
COALESCE:可変個の引数を取り、NULLでない最初の引数を返す標準関数

/* 完全外部結合は情報を「完全」に保存する(p.95) */
SELECT COALESCE(A.id, B.id) AS id,
       A.name AS A_name,
       B.name AS B_name
FROM Class_A  A  FULL OUTER JOIN Class_B  B
  ON A.id = B.id;

【外部結合が使えない環境での代替SQL
外部結合が使えない環境で同様の結果を得るには、左外部結合の結果と右外部結合の結果をUNIONする
 ※同じ結果は得られるがコードが冗長になり、UNIONを使用するのでパフォーマンスも落ちる

/* 完全外部結合が使えない環境での代替方法(p.96) */
SELECT A.id AS id, A.name, B.name
  FROM Class_A  A   LEFT OUTER JOIN Class_B  B
    ON A.id = B.id
UNION
SELECT B.id AS id, A.name, B.name
  FROM Class_A  A  RIGHT OUTER JOIN Class_B  B
    ON A.id = B.id;

【テーブル作成SQL

/* 完全外部結合 */
CREATE TABLE Class_A
(id char(1), 
 name varchar(30), 
 PRIMARY KEY(id));

CREATE TABLE Class_B
(id   char(1), 
 name varchar(30), 
 PRIMARY KEY(id));

INSERT INTO Class_A (id, name) VALUES('1', '田中');
INSERT INTO Class_A (id, name) VALUES('2', '鈴木');
INSERT INTO Class_A (id, name) VALUES('3', '伊集院');

INSERT INTO Class_B (id, name) VALUES('1', '田中');
INSERT INTO Class_B (id, name) VALUES('2', '鈴木');
INSERT INTO Class_B (id, name) VALUES('4', '西園寺');