67998


これまで INNER JOIN を一度も使用したことはないのですが、 INNER JOIN は、どういう時に使用するのですか？  
INNER JOIN を使用しないと、出来ない処理はありますか？

* * *

INNER JOIN の説明を読むと、両テーブルのカラム値が一致するデータだけ取得する、と書いてあるのですが、  
OUTER JOIN で、両テーブルのカラム値が一致するという条件を書けば良いだけだと思うのですが、そういう問題ではない？？

例えばですが、OUTER JOIN 後に、条件追記することで INNER JOIN と同じ結果を取得できますか？  
実際に実行するかどうかは別として、基本的な考え方としては下記認識で合っていますか？  
・INNER JOIN 取得結果から、OUTER JOIN 取得結果を 得ることは不可  
・OUTER JOIN 取得結果から、(条件追記することで)INNER JOIN 取得結果を 得ることは可


CC BY-SA 4.0
2020-06-24T10:57:33.680
67958
2020-06-25T15:47:16.593
2020-06-25T14:20:40.803
19110
7886
question
mysql sql
INNER JOIN は、どういう時に使用するのですか？ INNER JOIN でしか出来ないことはありますか？


> ・INNER JOIN 取得結果から、OUTER JOIN 取得結果を 得ることは不可

はい、不可能です。

> ・OUTER JOIN 取得結果から、(条件追記することで)INNER JOIN 取得結果を 得ることは可

はい、可能です。

* * *

# 詳細

`OUTER JOIN` は3つの種類があります。

  * `LEFT OUTER JOIN` （左外部結合）
  * `RIGHT OUTER JOIN` （右外部結合）
  * `FULL OUTER JOIN` （完全外部結合）

`LEFT JOIN` のように、`OUTER` を省略して書いても構いません。  
逆に、`LEFT/RIGHT/FULL` を省略して `OUTER JOIN` と書くことはできません。  
（ちなみに、`FROM A, B` のように書いた場合、`FROM A CROSS JOIN B` 相当になります）

質問者の `OUTER JOIN` がどれを指すか不明ですが、質問内容から `FULL OUTER JOIN` と仮定します。

以下のテーブルを使って、例を挙げます。

[code]

    Aテーブル  Bテーブル
    +------+   +------+
    | ID   |   | ID   |
    +------+   +------+
    | 1    |   | 1    |
    | 2    |   | 3    |
    +------+   +------+
    
[/code]

## 例1: `FROM A INNER JOIN B ON A.ID = B.ID`

AテーブルとBテーブルの両方に同じIDがある行のみ取得できます。

[code]

    +------+------+
    | A.ID | B.ID |
    +------+------+
    |    1 |    1 |
    +------+------+
    
[/code]

## 例2： `FROM A FULL OUTER JOIN B ON A.ID = B.ID`

AテーブルまたはBテーブルにある行が取得できます。

[code]

    +------+------+
    | A.ID | B.ID |
    +------+------+
    |    1 |    1 |
    |    2 | null |
    | null |    3 |
    +------+------+
    
[/code]

## 例3： `FROM A FULL OUTER JOIN B ON A.ID = B.ID WHERE A.ID = B.ID`

例2のテーブルができあがった後に、`A.ID = B.ID` となる行を抽出しています。

[code]

    +------+------+
    | A.ID | B.ID |
    +------+------+
    |    1 |    1 |
    +------+------+
    
[/code]

つまり、`INNER JOIN` と同じ結果になります。  
（データベース内部では、大体の場合 `INNER JOIN` と同じ処理に変換されます）

## 使い分け

適切に JOIN を使い分けることで、 **`ON` 句に結合条件、`WHERE` 句に抽出条件** を書けます。

例えば、`A.ID = B.ID` は抽出条件ではなく結合条件です。  
この場合、`INNER JOIN` を使って結合条件を `ON` 句に書いた方が、 **二つのテーブルをIDで結合している**
ということが一目でわかります。

逆に、`FULL OUTER JOIN` を使って `WHERE`
句に結合条件を書くと、抽出条件の中に結合条件が埋もれてしまうため、二つのテーブルの関係がぱっと見でわからなくなります。

## 参考

[7.2. テーブル式 - 第7章 問い合わせ - PostgreSQL
12.0文書](https://www.postgresql.jp/document/12/html/queries-table-
expressions.html#QUERIES-JOIN)


CC BY-SA 4.0
2020-06-25T15:20:35.687
67998
2020-06-25T15:41:08.850
2020-06-25T15:41:08.850
14334
14334
67958
answer


INNER JOIN と OUTER JOIN は状況に応じて使い分けるべき、別の演算です。MySQL では何も装飾のない `JOIN` は INNER
JOIN になるので、使ったことはあるのではないかと思います。

そもそも、関係データベースの JOIN 演算には次の 4 つの種類が知られています。

  * INNER JOIN
  * LEFT OUTER JOIN
  * RIGHT OUTER JOIN
  * FULL OUTER JOIN

これらはそれぞれ、対応する値が相手のテーブルに存在しなかったときにどうするか、が異なります。

例として『リレーショナルデータベース入門』（増永良文）に載っていたものを引用します。最初に次のようにふたつのテーブル「供給」と「需要」があったとします。

[![](https://i.stack.imgur.com/HzcSl.png)](https://i.stack.imgur.com/HzcSl.png)

このふたつのテーブルを、`供給.部品 = 需要.部品` という条件のもとでそれぞれ JOIN 演算すると次のようになります。

[![](https://i.stack.imgur.com/4ZbTU.png)](https://i.stack.imgur.com/4ZbTU.png)

それぞれの演算において相手のテーブルに対応する `部品`
があるかないかによって演算結果に特定の行ができるかできないかが変わってくるのがお分かりかと思います。この違いは、この後どのような演算をしたいのかによって

これらを理解していただいた上で質問文の質問に答えます。

> （INNER JOIN を使わずに）OUTER JOIN
> で、両テーブルのカラム値が一致するという条件を書けば良いだけだと思うのですが、そういう問題ではない？？

NULL のある行が生まれるか生まれないかの差異があるので、その条件だと代替はできません。

> OUTER JOIN 後に、条件追記することで INNER JOIN と同じ結果を取得できますか？

はい、無駄を許せば、一度 OUTER JOIN した後、その結果のテーブルに対して `供給.部品 = 需要.部品` な行だけ残るように WHERE
節を書けば実現できます。ただそんなことをするくらいなら最初から INNER JOIN を書けば良いでしょう（もっとも、MySQL
だとこのような条件は[最適化されて](https://dev.mysql.com/doc/refman/8.0/en/outer-join-
optimization.html) INNER JOIN 相当のクエリになることが多そうですが）。

* * *

補足：MySQL には FULL OUTER JOIN 構文は存在しないのでお気をつけください。参考: [Why does MySQL report a
syntax error on FULL OUTER JOIN?](https://stackoverflow.com/q/2384298/5989200)


CC BY-SA 4.0
2020-06-25T15:39:22.737
67999
2020-06-25T15:47:16.593
2020-06-25T15:47:16.593
19110
19110
67958
answer