複数の表からのデータの取り出し

現在勉強しているオラクルマスターブロンズ（SQL）についてまとめたものです。
自分のアウトプット用なので見やすさなどは期待しないでください。

# 複数の表の結合

## 結合とは

結合とは、**複数の表を関連づけてデータを取り出す機能**。
複数の表に分散しているデータを1つの結果として取り出したい場合は、SQL文で関連する表を結合することが必要になる。

複数の表を結合する方法はいくつかあり、最もシンプルな方法はFROM句に結合する表の名前をカンマで区切って指定する方法。
なお、この方法で結合した場合、表の**全ての組み合わせ**が表示される。

結合する表の両方に存在する列をSELECT句に指定するとエラーになる。
このような場合は、列名に**表接頭辞（表名）**を付けることで明示的にどの表のどの列という形式で指定し、列名のあいまいさを回避する必要がある。

なお、表接頭辞は結合する表に重複する列名がない場合でも使用できる。
表接頭辞を使用すれば、OracleサーバーがSQL文の構文を解析する際に列名の重複の有無をチェックする必要がなくなるため、わずかだが**SQL文のパフォーマンスが向上**する。

SELECT句に指定できる列別名と同様に、FROM句では**表別名**を指定でき、FROM句に指定した表名の後ろに１つ以上のスペースを入れて指定する。
なお、**表別名を指定すると、SQL文全体で元の表名は無効になる**。

## 結合構文の種類

SQL:1999結合構文とは、標準化団体によって標準化されたSQL:1999規格に準拠した結合構文で、**JOINキーワード**を使用して表を結合する。
また、結合条件は**ON句**に指定するが、必須ではない。

SQL:1999結合構文の結合のタイプ

| 結合のタイプ | キーワード |
|:--|:--|
| 等価結合（自然結合）| NATURAL JOIN |
| 等価結合（USING句を使用した結合） | JOINおよびUSING |
| 等価結合（ON句を使用した結合） | JOINおよびON |
| 非等価結合 | JOINおよびON |
| 自己結合 | JOINおよびON |
| 外部結合（左側外部結合） | LEFT [OUTER] JOINおよびON |
| 外部結合（右側外部結合） | RIGHT [OUTER] JOINおよびON |
| 外部結合（完全外部結合） | FULL [OUTER] JOINおよびON |
| クロス結合 | CROSS JOIN |

# 等価結合

等価結合とは、結合する２つの表の**特定の列の値が等しいデータだけを取り出す**結合で、内部結合や単純結合と呼ばれることもある。
等価結合は以下の３つの方法で実行できる。

- 自然結合
- USING句を使用した結合
- ON句を使用した結合

## 自然結合

**自然結合**とは、結合する２つの表に共通して存在する**同じ列名かつ同じデータ型の列**に基づいて表を結合する等価結合で、**NATURAL JOIN句**の前後に結合する表名を指定する。
また、自然結合には以下の特徴がある。

- 結合列が自動的に判断されるため、**明示的に結合条件を指定する必要はない**。
- 共通して存在する列が複数ある場合は、**すべての列が結合条件として使用される**。
- **データ型の異なる同名の列があるとエラーになる**。

結合する２つの表に共通して存在する列が複数ある場合は、**それらの全ての値が等しいデータのみ**が取り出されるため、自然結合ではいずれかの列だけを結合列に指定することはできない。

SQL:1999結合構文でも、多くの場合で表接頭辞を使用して列名を修飾できるが、自然結合の**結合列には表接頭辞を使用できない**。

## USING句を使用した結合

自然結合では結合列が自動的に判断されるが、USING句を使用した結合では**結合列を明示的に指定できる**。
USING句は主に以下のような場合に使用する。

- 結合列を明示的に指定してSQL文を分かりやすくしたい場合
- 結合する２つの表に共通して存在する列が複数ある場合に、その**いずれかを結合列として使用したい**場合。
- 列名が同じで**データ型が異なる列**を結合列として使用する場合。

USING句を使用した結合でも**結合列に表接頭辞を使用するとエラーになる**。

**１つの結合に対して**、NATURAL JOIN句とUSING句を**同時に使用することはできない**。

## ON句を使用した結合

自然結合やUSING句を使用した結合では２つの表にある同じ名前の列を使用して結合が行われるが、ON句を使用した結合では**異なる名前の列を使用して表を結合**することもできる。
ON句を使用した結合では、**ON句に続いて結合条件を指定**する。

ON句を使用した結合では、2つの表にある同じ名前の列をSELECT句やWHERE句などで使用する場合は**表接頭辞を使用して列名を修飾する必要がある**。

## Oracle独自結合構文による等価結合

Oracle独自結合構文には以下の特徴がある。

WHERE句に結合条件を指定し、結合条件以外の条件がある場合はAND演算子を使用して追加する。
そのため、結合条件と結合条件以外の条件がWHERE句に混在することになる。

SQL:1999結合構文のON句を使用した場合と同様に、2つの表に同じ名前の列がある場合は、表接頭辞を使用して修飾する必要がある。
なお、SQL:1999結合構文とOracle独自結合構文に**パフォーマンス上の差はない**。

## 3つ以上の表の結合

3つ以上の表を結合する場合は、基本的には結合する表の数だけJOIN 表名 ON 結合条件を繰り返し指定するといった形式になる。

**結合列の名前が同じで、データ型も同じ場合**（互換性のあるデータ型を含む）は、自然結合やUSING句を使用した結合でも、3つ以上の表を結合することができる。

なお、1つの結合ではNATURAL JOIN句とUSING句を同時に使用できないが、3つ以上の表を結合する場合のように、複数の結合を**1つのSQL文**で実行する場合はNATURAL JOIN句とUSING句、ON句を**同時に使用することができる**。

# その他の結合構文

**非等価結合**とは、結合条件に**＝（等価演算子）以外**の演算子を使用して、条件を満たすデータを取り出す結合。

**自己結合**とは、**同一の表に2つの表別名**を指定することで1つの表に見立ててデータを取り出す結合。

**外部結合**とは、結合条件を満たしたデータだけでなく、**結合条件を満たしていないデータも取り出す**結合。

外部結合には３種類あり、ON句に指定された結合条件を満たすデータとともに、左側外部結合がJOIN句の**左側**、右側外部結合が**右側**、完全外部結合が**左右**に指定された表のデータをそれぞれ全て取り出す。

Oracle独自結合構文で外部結合を行うには、**+（外部結合演算子）**を使用する。
+をWHERE句の条件の**左側**に付けると**右側外部結合**と同様の結果に、**右側**に付けると**左側外部結合**と同様の結果になる。
なお、完全外部結合に相当する構文はない。

**クロス結合**とは、**デカルト積**（結合する表に格納されているデータの**全ての組み合わせ。直積**ともいう）を戻す結合で、**CROSS JOINキーワード**を使用する。
実行結果には、多くの意味のないデータが含まれるため、通常ではあまり使用しないが、大量のサンプルデータを生成する際などに使用することがある。