結合とは
複数の表から必要なデータを取り出し、1つの結果セットとして返す操作。結合には「内部結合」「外部結合」「クロス結合(デカルト積)」などの種類があり、SQL標準構文と Oracle 独自構文の2系統が存在する。
結合の種類
内部結合(INNER JOIN)
結合条件を満たす行のみを返す最も基本的な結合。
SELECT e.empno, e.ename, d.dname
FROM emp e
INNER JOIN dept d ON e.deptno = d.deptno;
-
INNERキーワードは省略可能。JOINのみでも内部結合として動作する -
ON句に結合条件を記述する。列名が異なっていても結合可能
外部結合(OUTER JOIN)
結合条件を満たす行に加え、条件を満たさない行も含めて返す結合。条件を満たさない側の列は NULL で表示される。
左外部結合(LEFT OUTER JOIN)
FROM 句で左側に書いた表の全行を返す。右側の表に対応行がない場合は NULL を表示。
SELECT e.empno, e.ename, d.dname
FROM emp e
LEFT OUTER JOIN dept d ON e.deptno = d.deptno;
右外部結合(RIGHT OUTER JOIN)
FROM 句で右側に書いた表の全行を返す。左側の表に対応行がない場合は NULL を表示。
SELECT e.empno, e.ename, d.dname
FROM emp e
RIGHT OUTER JOIN dept d ON e.deptno = d.deptno;
完全外部結合(FULL OUTER JOIN)
両方の表の全行を返す。対応行がない側の列は NULL で表示。
SELECT e.empno, e.ename, d.dname
FROM emp e
FULL OUTER JOIN dept d ON e.deptno = d.deptno;
補足(外部結合の OUTER 省略):
LEFT OUTER JOINのOUTERは省略可能で、LEFT JOINと書いても同じ動作になる(RIGHT / FULL も同様)。
クロス結合(CROSS JOIN)
結合条件を指定せず、2つの表の全行の組み合わせ(デカルト積)を返す。
SELECT e.ename, d.dname
FROM emp e
CROSS JOIN dept d;
- 結果の行数は「表1の行数 × 表2の行数」になる
- Oracle 独自構文では、
FROM句に表名をカンマ区切りで並べWHERE句を省略した場合もクロス結合が実行される - 試験では「結合条件を省略・または記述が無効な場合にクロス結合が実行される」という点が問われる
結合の構文(4種類)
① ON句による結合
SQL標準構文。列名が異なっていても結合条件を自由に書ける最も汎用的な方法。
内部結合
SELECT e.empno, e.ename, d.dname
FROM emp e
[INNER] JOIN dept d
ON e.deptno = d.deptno;
-
INNERは省略可能 -
ON句には結合条件を明示的に記述する
外部結合
SELECT e.empno, e.ename, d.dname
FROM emp e
[LEFT | RIGHT | FULL] OUTER JOIN dept d
ON e.deptno = d.deptno;
ON句の注意点:
ON句を使った場合、結合列は両方の表に別々の列として存在したまま。そのためSELECT句で結合列を参照するときはe.deptno/d.deptnoのように表接頭辞で区別する必要がある。
② USING句による結合
SQL標準構文。2つの表に同名・同データ型の列が存在する場合に使用できる簡略構文。
内部結合
SELECT empno, ename, dname
FROM emp
[INNER] JOIN dept
USING (deptno);
外部結合
SELECT empno, ename, dname
FROM emp
[LEFT | RIGHT | FULL] OUTER JOIN dept
USING (deptno);
USING句の最重要制約(試験頻出):
USING句で指定した結合列は、SELECT句・WHERE句・ON句を含むSQL文のどこにも表接頭辞を付けてはいけない。付けるとORA-25154: column part of USING clause cannot have qualifierエラーになる。
-- ❌ エラー(USING列に表接頭辞を付けている)
SELECT e.deptno, d.dname
FROM emp e JOIN dept d
USING (deptno)
WHERE e.deptno = 10; -- ORA-25154
-- ✅ 正しい(USING列には接頭辞なし)
SELECT deptno, d.dname
FROM emp e JOIN dept d
USING (deptno)
WHERE deptno = 10;
ON句との違い:
USING句で結合すると、結合列は結果セットで1列に統合される(deptnoが1列だけになる)。一方ON句では両表の列が別々に残るため2列分存在する。
③ NATURAL JOIN(自然結合)
SQL標準構文。2つの表で名前とデータ型が一致するすべての列を自動的に結合列として使用する。
内部結合
SELECT empno, ename, dname
FROM emp
NATURAL [INNER] JOIN dept;
外部結合
SELECT empno, ename, dname
FROM emp
NATURAL [LEFT | RIGHT | FULL] OUTER JOIN dept;
NATURAL JOINの制約(試験頻出):
- 結合列を指定できない(自動で選ばれる)
- 同名・同データ型の列が複数ある場合、すべてが結合条件に適用される
- 結合列に表接頭辞を使用できない(USING句と同様)
- 同名だがデータ型が異なる列が存在する場合はエラーになる(この場合は
USING句を使う) -
NATURALとUSINGは同時に使用できない(排他的)
④ WHERE句による結合(Oracle独自 / 旧構文)
FROM 句にカンマ区切りで表を並べ、WHERE 句に結合条件を記述する Oracle 独自の旧来構文。
内部結合(等価結合)
SELECT e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;
-
FROM句の表の並び順に依存しないが、可読性は ANSI 構文より低い - 結合条件と絞り込み条件を
WHERE句にまとめて書ける - 結合条件を省略した場合または記述が無効の場合、クロス結合(デカルト積)が実行される
外部結合(Oracle独自 + 演算子)
WHERE 句で外部結合を行うには、Oracle 独自の (+) 演算子を使用する。
-- 左外部結合:emp の全行 + dept に対応行がない場合 NULL
SELECT e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno(+);
-- 右外部結合:dept の全行 + emp に対応行がない場合 NULL
SELECT e.empno, e.ename, d.dname
FROM emp e, dept d
WHERE e.deptno(+) = d.deptno;
(+)演算子の重要な注意点:
-
(+)を両方の表に指定しても完全外部結合にはならない(エラーまたは意図しない動作) - Oracle 11g 以降は非推奨。新規開発では ANSI 標準の
LEFT/RIGHT/FULL OUTER JOINを使うことが推奨される
「WHERE句での外部結合は SQL 標準に存在しない。Oracle 独自構文(+)のみで実現できるが非推奨」
結合構文の比較
| 観点 | ON句 | USING句 | NATURAL JOIN | WHERE句(旧来) |
|---|---|---|---|---|
| 標準規格 | ANSI/ISO SQL 標準 | ANSI/ISO SQL 標準 | ANSI/ISO SQL 標準 | Oracle 独自 |
| 列名が異なっても可 | ✅ 可 | ❌ 不可(同名必須) | ❌ 不可(同名・同型必須) | ✅ 可 |
| 結合列への表接頭辞 | ✅ 必要・使用可 | ❌ 使用不可(ORA-25154) | ❌ 使用不可 | ✅ 使用可 |
| 外部結合の対応 | ✅ LEFT/RIGHT/FULL | ✅ LEFT/RIGHT/FULL | ✅ LEFT/RIGHT/FULL |
(+) のみ(非推奨) |
| 完全外部結合 | ✅ FULL OUTER JOIN | ✅ | ✅ | ❌ 不可 |
結合の構文サポートの歴史
-
Oracle 独自の外部結合
(+):SQL 標準化に先行した Oracle 独自拡張として長年使われてきた -
ANSI/ISO SQL 標準構文:Oracle 9i Release 1 から、当時の最新標準である ANSI/ISO SQL:1999 に準拠した結合構文(
INNER JOIN、LEFT/RIGHT/FULL OUTER JOIN、NATURAL JOIN、USING句)をサポート - Oracle 11g 以降、
(+)演算子は非推奨となっており、保守目的以外では ANSI 標準構文を使うことが推奨されている
表接頭辞(表別名)
複数の表に同名の列がある場合、列名の前に「表名.」または「表別名.」を付けてどの表の列かを明示する。
-- 表名を接頭辞として使用
SELECT emp.empno, dept.dname
FROM emp, dept
WHERE emp.deptno = dept.deptno;
-- 表別名を接頭辞として使用(推奨)
SELECT e.empno, d.dname
FROM emp e, dept d
WHERE e.deptno = d.deptno;
- 表接頭辞を省略すると
ORA-00918: column ambiguously defined(列の定義が未確定)エラーになる - 表別名を付けた場合、以降は表別名のみを使う。元の表名と表別名を混在させることはできない
-
USING句・NATURAL JOINでは、結合列には表接頭辞を付けられない点に注意
試験で意識したいポイントまとめ
| ポイント | 内容 |
|---|---|
| INNER の省略 |
INNER JOIN の INNER は省略可能 |
| USING句の制約 | 結合列に表接頭辞不可(ORA-25154) |
| NATURAL JOIN の自動選択 | 同名・同データ型の列すべてが結合条件に |
| NATURAL JOIN と USING の排他 | 同時使用不可 |
(+) での完全外部結合 |
両方に (+) を付けても完全外部結合にはならない |
(+) の現在の位置づけ |
Oracle 11g 以降は非推奨 |
| 結合条件省略時の挙動 | クロス結合(デカルト積)が実行される |
| 表別名と表名の混在 | 表別名を付けたら元の表名は使えない |
| ANSI の正式名称 | 「米国国家規格協会」 |