3つ以上の表の結合
3つ以上の表を結合する場合は、JOIN を連続して記述することで実現できる。結合の種類(ON句・USING句・NATURAL JOIN)は組み合わせて使用することも可能。
ON句を使用した場合(最も汎用的)
SELECT e.empno, e.ename, d.dname, sg.grade
FROM emp e
JOIN dept d ON e.deptno = d.deptno
JOIN salgrade sg ON e.sal BETWEEN sg.losal AND sg.hisal;
- 各
JOINに対してON句で結合条件を個別に指定する - 列名が異なっていても結合できる点が USING・NATURAL JOIN との違い
USING句を使用した場合
SELECT empno, ename, dname, loc
FROM emp
JOIN dept USING (deptno)
JOIN locations USING (loc_id);
- 各
JOINに対してUSING句で同名の結合列を個別に指定する - USING句で指定した結合列は、
SELECT・WHERE句で表接頭辞を付けられない(ORA-25154)
NATURAL JOIN を使用した場合
SELECT empno, ename, dname
FROM emp
NATURAL JOIN dept
NATURAL JOIN locations;
- 各
NATURAL JOINごとに、同名・同データ型の列がすべて結合条件として自動使用される - 結合列に表接頭辞を付けられない
重要補足(試験頻出):
1つの結合(JOIN…ON/USING/NATURAL)の中で、NATURAL JOINとUSINGを同時に指定することはできないが、3つ以上の表の結合では、複数の JOIN を1つの SQL 文に書くため NATURAL JOIN と USING を同じ SQL 文中に混在させることは可能。
ただし、同じ JOIN ペアに対して両方を同時に指定することはできない。
-- ✅ 同一SQL文中でNATURAL JOINとUSINGを混在(別々のJOINペアに指定)
SELECT prod_id, prod_name, cust_id, cust_last_name
FROM products p
NATURAL JOIN sales s
JOIN customers c USING (cust_id);
自己結合(Self Join)
自己結合とは
同一の表を異なる表別名で2回参照し、表内の行同士を結合する操作。
1つの表の中に「従業員ID」と「上司ID(= 別の従業員のID)」のように親子関係・循環リレーションシップが存在する場合に使用される。
同一表を複数回参照するため、どちらの表(=行セット)を参照しているかを区別するために必ず表別名をつける必要がある。
基本構文
SELECT
worker.empno AS 社員番号,
worker.ename AS 社員名,
manager.empno AS 上司番号,
manager.ename AS 上司名
FROM emp worker
JOIN emp manager ON worker.mgr = manager.empno;
-
empテーブルをworker(部下側)とmanager(上司側)という2つの表別名で参照 - 結合にはON句が必須(USING句・NATURAL JOIN は同名列が必要なため自己結合には適さない)
- 上司IDが NULL(最上位の従業員)は内部結合では除外される。除外しないためには外部結合を使う
-- 最上位の従業員も含める(LEFT OUTER JOIN で自己結合)
SELECT
w.empno AS 社員番号,
w.ename AS 社員名,
m.ename AS 上司名
FROM emp w
LEFT OUTER JOIN emp m ON w.mgr = m.empno;
クロス結合(CROSS JOIN / デカルト積)
クロス結合とは
2つの表のすべての行を組み合わせた結果(デカルト積)を返す結合。結合条件を指定しない。
- 結果の行数 = 表1の行数 × 表2の行数
- 通常は意図せず発生するもので、業務では基本的に使わない
- 試験では「結合条件を省略・または記述が無効な場合にクロス結合が実行される」という点が問われる
① CROSS JOIN 構文(ANSI標準)
SELECT e.ename, d.dname
FROM emp e
CROSS JOIN dept d;
② カンマ区切りで表を列挙(Oracle旧来構文)
SELECT e.ename, d.dname
FROM emp e, dept d;
-- WHERE句を書かない → 結合条件なし → クロス結合
注意:カンマ区切りで表を列挙した場合、
WHERE句で結合条件を指定しないと意図せずクロス結合が実行される。
これは試験で「なぜ件数が多くなったか?」という形で問われることがある。
非等価結合(Non-Equi Join)
非等価結合とは
結合条件に =(等号)以外の演算子(BETWEEN・>・<・>=・<=・!= など)を使用する結合。
代表的な用途は「給与がどの給与ランクに属するか」のように、値が範囲内に収まるかどうかで結合する場合。
基本構文(ON句 + BETWEEN)
SELECT e.ename, e.sal, sg.grade
FROM emp e
JOIN salgrade sg ON e.sal BETWEEN sg.losal AND sg.hisal;
-
BETWEEN 下限値 AND 上限値で「sal が losal 以上 hisal 以下の行」と結合 - 等価(
=)での結合ができない場合に使用する
非等価結合は BETWEEN だけでなく >・<・>=・<= などの比較演算子全般を使用できる。
USING句・NATURAL JOINで非等価結合ができない理由
USING 句と NATURAL JOIN が非等価結合に使用できないのは、これらの構文が**「同名列の値が等しい(=)こと」を前提とした構文**であるためで、= 以外の演算子を結合条件として指定できる構文を持っていない。
非等価結合を行うには必ず ON 句(または Oracle 旧来の WHERE 句)を使う必要がある。
-- ❌ USING句では非等価結合不可(構文エラー)
-- JOIN salgrade USING (sal BETWEEN losal AND hisal) -- 不可
-- ✅ ON句であれば非等価結合が可能
JOIN salgrade sg ON e.sal BETWEEN sg.losal AND sg.hisal
各結合種別の制約まとめ
| 観点 | ON句 | USING句 | NATURAL JOIN |
|---|---|---|---|
| 非等価結合(BETWEEN等) | ✅ 可 | ❌ 不可 | ❌ 不可 |
| 列名が異なっても結合可 | ✅ 可 | ❌ 不可(同名必須) | ❌ 不可(同名・同型必須) |
| 結合列への表接頭辞 | ✅ 必要・使用可 | ❌ 使用不可(ORA-25154) | ❌ 使用不可 |
| 自己結合で使用可 | ✅ 可 | ❌ 非推奨(同名列が必要) | ❌ 非推奨 |
| 3表以上の結合 | ✅ 可 | ✅ 可 | ✅ 可 |
試験で意識したいポイントまとめ
| ポイント | 内容 |
|---|---|
| 自己結合で表別名は必須 | 同一表を区別するために表別名が必ず必要 |
| 自己結合はON句を使う | USING句・NATURAL JOINは自己結合に適さない |
| mgr=NULLの行 | 内部結合では除外される(含めるにはLEFT OUTER JOINを使う) |
| NATURAL JOIN と USING の混在 | 同一JOINペアには不可。別々のJOINペアなら同一SQL文内で混在可能 |
| 非等価結合はON句のみ | USING句・NATURAL JOINでは非等価結合不可 |
| 非等価結合の演算子 | BETWEEN以外にも >・<・>=・<=・!= なども使用可 |
| クロス結合の発生条件 | 結合条件を省略・または無効にした場合にデカルト積が発生 |
| カンマ区切りのWHERE省略 |
FROM 表1, 表2 でWHEREを書かないとクロス結合になる |