テーブル結合(JOIN)とは、 複数のテーブルを組み合わせてデータを取得する方法です。
JOIN
は
SELECT
文で指定できる句の一つで、実際の開発現場では頻繁に使われます。むしろ、JOIN を使わずにデータを取得するケースのほうが少ないほどです。
JOIN にはいくつかの種類がありますが、特に
使用頻度が高いのは
LEFT JOIN
です。
他にも
CROSS JOIN
や
RIGHT JOIN
などがありますが、利用する機会は少ないため、必要になったときに覚えれば問題ありません。
それでは、
LEFT JOIN
の仕組みを
実際の例を使って見ていきましょう。
以下がLEFT JOINの基本的なSQL構文です。
SELECT
A.列名1, A.列名2, B.列名3
FROM
テーブルA AS A
LEFT JOIN
テーブルB AS B
ON
A.共通カラム = B.共通カラム;
テーブルA
(左のテーブル)のすべての行が返されます。
テーブルB
(右のテーブル)に対応するデータがない場合は、
NULL
が入ります。
たとえば、「顧客(customers)」テーブルと「注文(orders)」テーブルがあり、各顧客が過去に注文をしたかどうかを取得したい場合、以下のようにLEFT JOINを使用できます。
customer_id | name |
---|---|
1 | 田中 |
2 | 鈴木 |
3 | 佐藤 |
order_id | customer_id | product |
---|---|---|
101 | 1 | ノートPC |
102 | 2 | スマホ |
SELECT
customers.customer_id,
customers.name,
orders.product
FROM
customers
LEFT JOIN
orders
ON
customers.customer_id = orders.customer_id;
customer_id | name | product |
---|---|---|
1 | 田中 | ノートPC |
2 | 鈴木 | スマホ |
3 | 佐藤 | NULL |
この結果から、佐藤さん(customer_id=3)は注文履歴がないことが分かります。
INNER JOIN
と
LEFT JOIN
の違いに注意しましょう。
SELECT
customers.customer_id,
customers.name,
orders.product
FROM
customers
INNER JOIN
orders
ON
customers.customer_id = orders.customer_id;
customer_id | name | product |
---|---|---|
1 | 田中 | ノートPC |
2 | 鈴木 | スマホ |
INNER JOINでは、「一致するデータのみ」が返るため、注文がない佐藤さん(customer_id=3)のデータは含まれません。
→ LEFT JOINは、関連データがない場合でも左側のテーブルのデータを維持し、NULLを返すのが特徴です。
このようによく似ているため、LEFT JOINでなくINNER JOINを採用するエンジニアもいます。
LEFT JOINは1つのテーブルだけでなく、 複数のテーブルを結合することも可能です。というより実際、このような使われ方をされることの方が多いです。たとえば、顧客(customers)、注文(orders)、配送情報(shipments)の3つのテーブルを結合し、各顧客の注文と配送状況を取得するケースを考えます。
customer_id | name |
---|---|
1 | 田中 |
2 | 鈴木 |
3 | 佐藤 |
order_id | customer_id | product |
---|---|---|
101 | 1 | ノートPC |
102 | 2 | スマホ |
shipment_id | order_id | status |
---|---|---|
201 | 101 | 配送済み |
202 | 102 | 配送中 |
SELECT
customers.customer_id,
customers.name,
orders.product,
shipments.status
FROM
customers
LEFT JOIN
orders
ON
customers.customer_id = orders.customer_id
LEFT JOIN
shipments
ON
orders.order_id = shipments.order_id;
customer_id | name | product | status |
---|---|---|---|
1 | 田中 | ノートPC | 配送済み |
2 | 鈴木 | スマホ | 配送中 |
3 | 佐藤 | NULL | NULL |
このクエリでは、
NULL
が入る
このように、複数のLEFT JOINを使うことで、必要なデータを組み合わせることができます。
以下のテーブル
employees
と
departments
を元に、LEFT JOINを使用して全社員の部署情報を取得するSQLを作成してください。
employees(社員情報)
employee_id | name | department_id |
---|---|---|
1 | 田中 | 1 |
2 | 鈴木 | 2 |
3 | 佐藤 | NULL |
departments(部署情報)
department_id | department_name |
---|---|
1 | 営業部 |
2 | 開発部 |
期待される結果
employee_id | name | department_name |
---|---|---|
1 | 田中 | 営業部 |
2 | 鈴木 | 開発部 |
3 | 佐藤 | NULL |
LEFT JOINを使用すると、右側のテーブルに対応するデータがない場合
NULL
になります。
employees
テーブルに所属部署がない社員(department_idがNULL)のみを取得するSQLを作成してください。
employees
テーブルと
departments
テーブルを
INNER JOINを使って結合した場合、どのような結果になりますか?
LEFT JOINとの違いを説明してください。
次の
orders
テーブルと
shipments
テーブルを
customers
テーブルと結合し、各顧客の注文情報と配送状況を取得するSQLを作成してください。
customers(顧客情報)
customer_id | name |
---|---|
1 | 田中 |
2 | 鈴木 |
3 | 佐藤 |
orders(注文情報)
order_id | customer_id | product |
---|---|---|
101 | 1 | ノートPC |
102 | 2 | スマホ |
shipments(配送情報)
shipment_id | order_id | status |
---|---|---|
201 | 101 | 配送済み |
202 | 102 | 配送中 |
期待される結果
customer_id | name | product | status |
---|---|---|---|
1 | 田中 | ノートPC | 配送済み |
2 | 鈴木 | スマホ | 配送中 |
3 | 佐藤 | NULL | NULL |