JOINとは

データの結合

JOINは、複数のテーブル間で関連するデータを結合するためのSQLです。JOINを使用すると複数のテーブルの列を関連づけながら、包括的な結果を取得することができます。

リレーションの確認

JOINを利用するには、テーブルのリレーションを確認する必要があります。各テーブルのカラムの値がリレーション(関連)していることが前提です。

ER図

リレーションを視覚的に理解するのに、ER図というデータベーステーブルの関連図があります。phpMyAdmin*ではメニューの「デザイナ」からER図が表示できます。

ER図は、DDLであらかじめリレーションの定義していれば、テーブルカラムが線で結ばれます。

ER図

JOINの種類

RDBでは、いくつかのJOINの種類が利用できます。JOINは、内部結合(INNER)外部結合(OUTER) にわかれます。

INNER JOIN

INNER JOIN(JOIN)は2つのテーブルで共有される行を内部結合し、共有値が一致する行のみが結果に表示されます。

LEFT JOIN

LEFT JOIN(LEFT OUTER JOIN)は、左側のテーブルのすべての行を保持し、右側のテーブルの共有される行を外部結合します。右側のテーブルに一致する行がない場合、NULL値が表示されます。

RIGHT JOIN

RIGHT JOIN(RIGHT OUTER JOIN)ともいい、右側のテーブルのすべての行を保持し、左側のテーブルの共有される行を外部結合します。左側のテーブルに一致する行がない場合、NULL値が表示されます。

FULL JOIN

FULL JOIN(FULL OUTER JOIN)ともいい、左右のテーブルのすべての行を保持し、共有される行を完全外部結合します。一致しない場合は、NULL値が表示されます。

  • MySQLでは FULL JOIN は利用できないため、LEFTとRIGHTを組み合わせます。

基本構文

SELECT * FROM table1 JOIN table2 ON table1.column = table2.column;

INNER JOIN

INNER JOINの基本

「user_items.user_id」と「users.id」がリレーションキーで、INNER JOIN(内部結合)します。

SELECT 
  users.id,
  users.name,
  user_items.user_id, 
  user_items.item_id, 
  user_items.created_at
FROM user_items 
INNER JOIN users ON user_items.user_id = users.id;

「users.id = user_items.user_id」のレコードのみ選択されました。

結果例
id name user_id item_id created_at	
1 三宅 直子 1 1 2023-06-12 13:39:45
2 渡辺 直人 2 1 2023-06-12 13:39:47
1 三宅 直子 1 3 2023-06-12 13:40:45
3 三宅 聡太郎 3 2 2023-06-12 13:41:02

INNERの省略

INNER JOINは、JOINと省略できます

SELECT 
  users.id,
  users.name,
  user_items.user_id, 
  user_items.item_id, 
  user_items.created_at
FROM user_items 
JOIN users ON user_items.user_id = users.id;

順番を変えても基本は同じ

INNER JOIN は、FROMJOINの順番を変えても、基本的に結果は同じになります。

SELECT 
  users.id,
  users.name,
  user_items.user_id, 
  user_items.amount, 
  user_items.created_at
FROM users 
JOIN user_items ON user_items.user_id = users.id;
結果例
id name user_id amount created_at	
1 三宅 直子 1 3 2023-06-12 13:39:45
2 渡辺 直人 2 1 2023-06-12 13:39:47
1 三宅 直子 1 2 2023-06-12 13:40:45
3 三宅 聡太郎 3 2 2023-06-12 13:41:02

「user_items」に「items」を INNER JOIN

「user_items.item_id」と「items.id」がリレーションキーで、INNER JOINします。

SELECT 
  items.id,
  items.name,
  user_items.user_id, 
  user_items.item_id, 
  user_items.created_at
FROM user_items 
INNER JOIN items ON user_items.item_id = items.id;

「items.id = user_items.item_id」のレコードのみ選択されました。

結果例
id	name user_id item_id	created_at	
1 コーヒー 1 1 2023-06-12 13:39:45
1 コーヒー 2 1 2023-06-12 13:39:47
2 紅茶 3 2 2023-06-12 13:41:02
3 ほうじ茶 1 3 2023-06-12 13:40:45

OUTER JOIN

LEFT JOIN

「users」に「user_items」を LEFT JOIN

「users」を基準に「users.id = user_items.user_id」でLEFT JOINします。

SQL
SELECT 
  users.id,
  users.name,
  user_items.user_id, 
  user_items.item_id, 
  user_items.created_at
FROM users 
LEFT JOIN user_items ON user_items.user_id = users.id;

「users」(左)に「user_items」(右)がLEFTで結合し、関連するレコードが表示されました。一致しないレコードはNULLとなります。

id name user_id amount created_at	
1 三宅 直子 1 3 2023-06-12 13:39:45
2 渡辺 直人 2 1 2023-06-12 13:39:47
1 三宅 直子 1 2 2023-06-12 13:40:45
3 三宅 聡太郎 3 2 2023-06-12 13:41:02
4 原田 真綾 NULL NULL NULL
5 井上 亮介 NULL NULL NULL
...

「user_items」に「users」を LEFT JOIN

今度は「user_items」テーブルを基準に「users.id = user_items.user_id」でLEFT JOINします。

SQL
SELECT 
  users.id,
  users.name,
  user_items.user_id, 
  user_items.item_id, 
  user_items.created_at
FROM user_items 
LEFT JOIN users ON user_items.user_id = users.id;

「user_items」(左)に「users」(右)がLEFTで結合し、関連するレコードが表示されました。

結果例
id name user_id amount created_at	
1 三宅 直子 1 3 2023-06-12 13:39:45
2 渡辺 直人 2 1 2023-06-12 13:39:47
1 三宅 直子 1 2 2023-06-12 13:40:45
3 三宅 聡太郎 3 2 2023-06-12 13:41:02
結果

RIGHT JOIN

「user_items」を基準

「user_items」でRIGHT JOINします。

SQL
SELECT 
  users.id,
  users.name,
  user_items.user_id, 
  user_items.item_id, 
  user_items.created_at
FROM users RIGHT JOIN user_items 
ON user_items.user_id = users.id;

結果的に、INNER JOINと同じになりました。

結果例

右側を「users」

「users」でRIGHT JOINします。

SQL
SELECT 
  users.id,
  users.name,
  user_items.user_id, 
  user_items.item_id, 
  user_items.created_at
FROM user_items RIGHT JOIN users 
ON user_items.user_id = users.id;

結果的に「users」を左側とした LEFT JOINと同じになりました。

結果

基本は INNER JOIN と LEFT JOIN

INNER JOINLEFT JOINだけで、通常の結合処理ができます。RIGHT JOINは利用頻度が少ないかもしれません。

複数のJOIN

複数のJOINを使用することで、複数のテーブルと結合できるため、より複雑なデータ操作ができます。

3つのテーブルのINNER JOIN

table1、table2、table3の3つのテーブルをINNER JOINで結合しています。

SELECT *
FROM table1
INNER JOIN table2 ON table1.key = table2.key
INNER JOIN table3 ON table2.key = table3.key;

JOINの順序に注意

JOINによる結合の順序によって、結果が異なることがあるため注意が必要です。適切な結合順序を指定しましょう。

「user_items」に「users」と「items」を内部結合

SELECT 
  users.name,
  items.name,
  user_items.amount,
  user_items.total_price,
  user_items.created_at
FROM user_items 
JOIN users ON user_items.user_id = users.id
JOIN items ON user_items.item_id = items.id;