SQL JOINとは?
リレーショナルデータベースはデータを複数のテーブルに分けて保存します。JOINは分割されたテーブルを特定の条件(主に外部キーと主キーの関係)で結合し、一つの結果セットにするSQL演算です。
ERDでテーブル間の関係線として表現されるものが、実際のクエリではJOINとして実装されます。ERDをしっかり理解すると、JOINクエリの作成も自然にできるようになります。
サンプルテーブル
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT REFERENCES users(id),
amount DECIMAL(10,2)
);
INSERT INTO users VALUES (1,'Alice'), (2,'Bob'), (3,'Carol');
INSERT INTO orders VALUES (1,1,50.00),(2,1,30.00),(3,2,80.00),(4,NULL,20.00);
-- 注文4はuser_idがNULL、Carolは注文なし
INNER JOIN:積集合
両方のテーブルに存在する行だけを返します。最もよく使われるJOINです。
SELECT u.name, o.amount
FROM users u
INNER JOIN orders o ON u.id = o.user_id;
| name | amount |
|---|---|
| Alice | 50.00 |
| Alice | 30.00 |
| Bob | 80.00 |
Carolは注文がないため除外。注文4(user_id = NULL)も除外されます。
LEFT JOIN:左テーブル全行を保持
左テーブル(users)の全行を返し、右テーブル(orders)に一致がなければNULLで補完します。
SELECT u.name, o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
| name | amount |
|---|---|
| Alice | 50.00 |
| Alice | 30.00 |
| Bob | 80.00 |
| Carol | NULL |
Carolが注文なしでNULLとして含まれます。**「一度も注文したことがないユーザーを探す」**ようなクエリに有効です。
SELECT u.name
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE o.id IS NULL;
RIGHT JOIN:右テーブル全行を保持
LEFT JOINの逆で、右テーブルの全行を返します。
SELECT u.name, o.amount
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;
| name | amount |
|---|---|
| Alice | 50.00 |
| Alice | 30.00 |
| Bob | 80.00 |
| NULL | 20.00 |
注文4が含まれ、ユーザー名はNULL。実務ではLEFT JOINに書き換えることが多いです。
FULL OUTER JOIN:和集合
両方のテーブルの全行を返します。一致しない側はNULL。
SELF JOIN:自己結合
同じテーブルを2回参照します。従業員と上司の関係など階層構造データに活用します。
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
ERDの関係とJOINの対応
ERDの関係線はJOINのON条件に直接変換されます:
- 1:N関係(users → orders):
JOIN orders ON users.id = orders.user_id - N:M関係(students ↔ courses via enrollments):中間テーブルを介した2回のJOIN
- FKがNULL許可:LEFT JOINの使用を検討
まとめ
JOINはリレーショナルデータベースの核心機能です。ERDでテーブルの関係を視覚化すると、どのJOINをどう使うべきかが直感的に分かります。Erdmatesでテーブル構造を設計し、AI自然言語クエリ機能で複雑なJOINクエリを自動生成してみてください。