データベースの真価を発揮!複数のテーブルから情報をまとめて取得しよう
これまでは基本的に1つのテーブルからデータを取得する方法を学んできましたね。しかし、実際のデータベースでは、関連する情報が複数のテーブルに分割されて格納されていることがほとんどです(これを正規化といいます)。
例えば、「どの生徒がどの部活に所属しているか」を知りたい場合、「生徒情報テーブル」と「部活情報テーブル」の2つを見る必要があります。このように、複数のテーブルを特定の条件(共通の列など)でつなぎ合わせて、1つの結果として取得する操作がテーブル結合(JOIN)です。JOINをマスターすれば、SQLで扱える情報の幅が格段に広がりますよ!🎉
JOINの基本:INNER JOIN
最もよく使われるJOINが INNER JOIN
です。これは、2つのテーブル間で指定した条件に一致する行だけを結合します。条件に一致しない行は結果に含まれません。
例として、以下の2つのテーブルを考えてみましょう。
テーブル例
students テーブル
student_id | name | club_id |
---|---|---|
1 | 田中 太郎 | 101 |
2 | 佐藤 花子 | 102 |
3 | 鈴木 一郎 | 101 |
4 | 高橋 良子 | NULL |
clubs テーブル
club_id | club_name |
---|---|
101 | サッカー部 |
102 | テニス部 |
103 | 吹奏楽部 |
この2つのテーブルを使って、「生徒の名前」と「所属している部活の名前」を取得してみましょう。students
テーブルのclub_id
とclubs
テーブルのclub_id
が一致する行を結合します。
INNER JOIN の構文
SELECT
t1.column1, t1.column2, -- テーブル1から取得したい列
t2.column1, t2.column2 -- テーブル2から取得したい列
FROM
table1 AS t1 -- テーブル1(エイリアス t1 を使用)
INNER JOIN
table2 AS t2 -- テーブル2(エイリアス t2 を使用)
ON
t1.common_column = t2.common_column; -- 結合条件 (共通の列を指定)
INNER JOIN の実行例
SELECT
s.name, -- studentsテーブルのname列
c.club_name -- clubsテーブルのclub_name列
FROM
students AS s -- studentsテーブルを s というエイリアスで参照
INNER JOIN
clubs AS c -- clubsテーブルを c というエイリアスで参照
ON
s.club_id = c.club_id; -- sテーブルのclub_idとcテーブルのclub_idが一致する行を結合
実行結果
name | club_name |
---|---|
田中 太郎 | サッカー部 |
佐藤 花子 | テニス部 |
鈴木 一郎 | サッカー部 |
結果を見ると、students
テーブルの 高橋さん (club_id
が NULL) と、clubs
テーブルの 吹奏楽部 (club_id
103 に対応する生徒がいない) は、結合条件に一致する相手がいないため、結果に含まれていないことがわかります。これが INNER JOIN
の特徴です。まさに、両方のテーブルに存在する情報だけを取り出すイメージですね🤝。
片方のテーブルを基準にする:LEFT JOIN
次にLEFT JOIN
(LEFT OUTER JOIN
とも呼ばれます)を見てみましょう。これは、左側のテーブル(FROM句の直後に書かれたテーブル)の行はすべて結果に含め、右側のテーブル(JOIN句の後に書かれたテーブル)からは結合条件に一致する行だけを結合します。もし右側のテーブルに一致する行がない場合は、右側のテーブルの列には NULL
が入ります。
「すべての生徒について、所属している部活名を表示したい(部活に所属していない生徒もリストには含めたい)」という場合に便利です。
LEFT JOIN の構文
SELECT
t1.column1, t1.column2,
t2.column1, t2.column2
FROM
table1 AS t1 -- 左側のテーブル (このテーブルの行はすべて結果に含まれる)
LEFT JOIN
table2 AS t2 -- 右側のテーブル
ON
t1.common_column = t2.common_column; -- 結合条件
LEFT JOIN の実行例
先ほどのテーブルを使って、全生徒とその所属部活(未所属含む)を表示してみましょう。左側のテーブルをstudents
にします。
SELECT
s.name,
c.club_name -- 一致しない場合は NULL になる
FROM
students AS s -- 左側のテーブル (基準)
LEFT JOIN
clubs AS c -- 右側のテーブル
ON
s.club_id = c.club_id; -- 結合条件
実行結果
name | club_name |
---|---|
田中 太郎 | サッカー部 |
佐藤 花子 | テニス部 |
鈴木 一郎 | サッカー部 |
高橋 良子 | NULL |
INNER JOIN
の結果と比較すると、students
テーブルに存在する 高橋さん が結果に含まれていることがわかります。高橋さんは club_id
が NULL で、clubs
テーブルに対応する行がないため、club_name
列には NULL
が入っています。このように、LEFT JOIN
は左側のテーブルを主軸としてデータを取得したい場合に役立ちます👍。
その他の JOIN (RIGHT JOIN, FULL OUTER JOIN)
INNER JOIN
と LEFT JOIN
の他にも、いくつかのJOINがあります。簡単に紹介します。
-
RIGHT JOIN (RIGHT OUTER JOIN):
LEFT JOIN
の逆で、右側のテーブルの行をすべて含み、左側のテーブルからは一致する行のみを結合します。一致しない場合は左側の列がNULL
になります。
実行すると、吹奏楽部 (部員がいない) も結果に含まれ、対応する-- clubs テーブルを基準に結合 (LEFT JOINでテーブル順を入れ替えるのと同じ結果) SELECT s.name, c.club_name FROM students AS s RIGHT JOIN clubs AS c ON s.club_id = c.club_id;
s.name
はNULL
になります。 -
FULL OUTER JOIN: 両方のテーブルのすべての行を含みます。結合条件に一致する行は結合し、どちらかのテーブルにしか存在しない行は、相手のテーブルの列が
NULL
になります。INNER JOIN
,LEFT JOIN
,RIGHT JOIN
の結果をすべて合わせたようなイメージです。(ただし、すべてのデータベースシステムでサポートされているわけではありません。)-- 全生徒と全部活を表示 (対応がなくても NULL で表示) -- 注意: MySQLなど一部のDBMSでは FULL OUTER JOIN は直接サポートされていません SELECT s.name, c.club_name FROM students AS s FULL OUTER JOIN clubs AS c ON s.club_id = c.club_id;
-
CROSS JOIN: 結合条件を指定せず、すべての行の組み合わせ(直積)を生成します。あまり使う機会は多くありませんが、組み合わせを網羅的にリストアップしたい場合などに使われることがあります。
-- students と clubs の全組み合わせを生成 SELECT s.name, c.club_name FROM students AS s CROSS JOIN clubs AS c;
まずは INNER JOIN
と LEFT JOIN
をしっかり理解し、使いこなせるようになることが重要です。状況に応じて適切なJOINを選べるようになりましょう!😊
まとめ
今回は、複数のテーブルを結合する JOIN について学びました。
- JOIN: 複数のテーブルを共通の列をキーにして結合する操作。
- INNER JOIN: 両方のテーブルに結合条件を満たす行が存在する場合のみ結果を返す。
- LEFT JOIN: 左側のテーブルの行をすべて返し、右側のテーブルは条件に合う行のみ結合(合わない場合はNULL)。
RIGHT JOIN
やFULL OUTER JOIN
など、他の種類のJOINもある。
JOINは、リレーショナルデータベースの強力な機能の一つです。最初は少し難しく感じるかもしれませんが、実際に手を動かして色々なテーブルを結合してみることで、理解が深まります。頑張ってください!💪
次のステップでは、「自己結合」や「多段結合」といった、さらに応用的なテーブル結合の方法を見ていきます。
コメント