大規模データを扱うにあたり、内部結合や外部結合の仕組みを理解できていなかった部分があったため改めて理解するための備忘録。
JOINの種類まとめ
内部結合と外部結合の違いについての簡単なまとめです。
INNERやOUTERはそれぞれ省略可能で、結合時のふるまいが大きく異なります。
内部結合 | 外部結合 | |
---|---|---|
JOIN句 | INNER JOIN | LEFT OUTER JOIN RIGHT OUTER JOIN |
省略形 | JOIN | LEFT JOIN RIGHT JOIN |
結合時のふるまい | 片方のテーブルに存在しない場合は結合結果から消去される | 片方のテーブルに存在しない場合は値がNULLで行を生成 |
内部結合とは
内部結合は結合する両方のテーブルに存在するデータを抽出します。
たとえば以下のようなデータで結合時のふるまいを見てみましょう。
Fruitテーブル
id | name |
---|---|
1 | りんご |
2 | みかん |
3 | ぶどう |
4 | もも |
Stockテーブル
fruit_id | quantity |
---|---|
1 | 10 |
2 | 20 |
3 | 30 |
5 | 50 |
Fruitテーブルの「id」とStockテーブルの「fruit_id」で内部結合して、果物ごとの在庫数を抽出する場合を考えてみます。
SELECT
*
FROM
Fruit
INNER JOIN
Stock
ON
Fruit.id = Stock.fruit_id;
実行結果
id | name | fruit_id | quantity |
---|---|---|---|
1 | りんご | 1 | 10 |
2 | みかん | 2 | 20 |
3 | ぶどう | 3 | 30 |
内部結合の結果、Fruitテーブルの「もも」データはStockテーブルに存在しないため消去されました。
反対にStockテーブルのfruit_idが5のデータはFruitテーブルに存在しないため消去されました。
このように、結合する両方のテーブルに存在するデータのみを抽出するが内部結合です。
外部結合とは
外部結合とは結合するテーブルに対してデータの存在する・しないを問わずにテーブルを結合しデータを抽出します。
LEFT (OUTER) JOIN の場合は結合元のテーブルのレコードを、RIGHT (OUTER) JOIN の場合は結合先のテーブルのレコードを全件表示します。
【左外部結合】LEFT (OUTER) JOIN
内部結合の例で使用したデータを使って動作を見てみます。
SELECT
*
FROM
Fruit
LEFT JOIN
Stock
ON
Fruit.id = Stock.fruit_id;
実行結果
id | name | fruit_id | quantity |
---|---|---|---|
1 | りんご | 1 | 10 |
2 | みかん | 2 | 20 |
3 | ぶどう | 3 | 30 |
4 | もも | NULL | NULL |
「もも」のデータはStockテーブルに存在しませんがFuitテーブルに存在するため消去されませんでした。
このように、左外部結合は結合元(From句)のテーブルのレコードを全て抽出します。
【右外部結合】RIGHT (OUTER) JOIN
右外部結合も同様に見てみましょう。
SELECT
*
FROM
Fruit
RIGHT JOIN
Stock
ON
Fruit.id = Stock.fruit_id;
実行結果
id | name | fruit_id | quantity |
---|---|---|---|
1 | りんご | 1 | 10 |
2 | みかん | 2 | 20 |
3 | ぶどう | 3 | 30 |
NULL | NULL | 5 | 50 |
先ほどとは反対に右外部結合は結合先(JOIN句)のテーブルのレコードを全て抽出します。
Stockテーブルのfruit_idが5のデータはFruitテーブルに存在しないですが、消去されませんでした。
おまけ:データを絞り込むときの注意点
外部結合ではWHERE句とJOIN句のどちらで絞り込むかで結果が異なる点に注意が必要です。
「Stockテーブルのfruit_idが1のデータ」で絞り込んだときの動きをみてみましょう。
WHERE句で絞り込む場合
SELECT
*
FROM
Fruit
LEFT JOIN
Stock
ON
Fruit.id = Stock.fruit_id
WHERE
Stock.fruit_id = 1;
実行結果
id | name | fruit_id | quantity |
---|---|---|---|
1 | りんご | 1 | 10 |
WHER句で絞り込むと「Fruitテーブルのidが1のデータ」のみが抽出されます。
JOIN句で絞り込む場合
SELECT
*
FROM
Fruit
LEFT JOIN
Stock
ON
Fruit.id = Stock.fruit_id
AND
Stock.fruit_id = 1;
実行結果
id | name | fruit_id | quantity |
---|---|---|---|
1 | りんご | 1 | 10 |
2 | みかん | NULL | NULL |
3 | ぶどう | NULL | NULL |
4 | もも | NULL | NULL |
JOIN句に記載した場合、Stockテーブルのデータは絞り込まれますがFruitテーブルは全件抽出されます。
このように外部結合ではWHERE句とJOIN句のどちらで絞り込むかで結果が変わる点に注意してください。