SQLのINNER JOIN(内部結合)

INNER JOIN(内部結合)とは?
INNER JOIN(内部結合)とは、その名の通りテーブルとテーブルを結合するためのSQL構文です。そして、INNER(内部)であることの特徴は、テーブルとテーブルの互いの条件に一致するレコード(データ行)をのみを抽出するという点です。

画像:INNER JOIN(内部結合)の解説図
例えば、従業員テーブルと部署テーブルそれぞれに部署番号があるときに、その列を結合条件にして結びつけて検索する場合に、INNER JOINは有効です。

そんなINNER JOINの構文を見ていきます。
INNER JOINの構文
INNER JOINのSQLの構文は次の通りです。
SELECT
a.列名,
b.列名
FROM
テーブルa
INNER JOIN
テーブルb
ON
a.列名 = b.列名 -- 結合条件
テーブル間を結合する条件はON句につづけて、一般に主キー(PRIMARY KEY)と外部キーを”=”(イコール)演算子で関連づけます。次項では、実際にINNER JOINを使ったSQLのサンプルコードをみていきます!
なお、主キー(PRIMARY KEY)については、こちらで詳しく解説していますので、ぜひ参考にしてください。
【SQL入門】PRIMARY KEY(主キー)制約とは?追加や削除についても解説
外部キーについては、こちらで詳しく解説しています。
【SQL入門】外部キーとは?主キーとの関係や作成方法について解説
INNER JOINでテーブル結合してみる
従業員テーブルと部署テーブルをINNER JOINを使ってテーブル結合するサンプルコードを確認してみましょう。はじめに従業員テーブルと部署テーブルを作成します。
従業員テーブル:
CREATE TABLE sample1_employees (
no int NOT NULL, -- 従業員番号
department_no char(5), -- 部署番号
last_name varchar(255), -- 名
first_name varchar(255), -- 姓
PRIMARY KEY (no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- テストデータ
INSERT INTO sample1_employees VALUES('10001', 'A0001','侍','太郎');
INSERT INTO sample1_employees VALUES('10002', 'A0001','侍','次郎');
INSERT INTO sample1_employees VALUES('10003', 'A0002','侍','花子');
INSERT INTO sample1_employees VALUES('10004', 'A0003','侍','三郎');
部署テーブル:
CREATE TABLE sample1_departments (
department_no char(5), -- 部署番号
department_name varchar(255), -- 部署名
PRIMARY KEY (department_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- テストデータ
INSERT INTO sample1_departments VALUES('A0001', 'アプリ開発部');
INSERT INTO sample1_departments VALUES('A0002', 'データベース開発部');
INSERT INTO sample1_departments VALUES('B0003', 'Webデザイン部');
つづいて、SQLを実行してみます。
SELECT
*
FROM
sample1_employees a -- 従業員テーブル 別名a
INNER JOIN
sample1_departments b -- 部署テーブル 別名b
ON
a.department_no = b.department_no; -- a.部署番号 = b.部署番号
実行結果:
+-------+---------------+-----------+------------+---------------+-----------------------------+
| no | department_no | last_name | first_name | department_no | department_name |
+-------+---------------+-----------+------------+---------------+-----------------------------+
| 10001 | A0001 | 侍 | 太郎 | A0001 | アプリ開発部 |
| 10002 | A0001 | 侍 | 次郎 | A0001 | アプリ開発部 |
| 10003 | A0002 | 侍 | 花子 | A0002 | データベース開発部 |
+-------+---------------+-----------+------------+---------------+-----------------------------+
このように、従業員テーブルと部署テーブルをINNER JOINで結合して検索することができました。部署テーブルに部署番号(department_no)“A0003″が存在しないため、従業員テーブルの”侍 三郎さんは検索されないことが確認できたかと思います。
次項では、結合したテーブルの任意の列をSELECTする方法について説明します。
結合テーブルを指定してSELECTする
INNER JOINで結合したテーブルの任意の列を指定してSELECTするためには、
SELECT テーブルA.列名, テーブルB.列名 FROM テーブルA INNER JOIN テーブルB
のように列名の前にテーブル名を記述します。
- 従業員テーブル.従業員番号
- 部署テーブル.部署番号
- 部署テーブル.部署名
- 従業員テーブル.名
をSELECTするサンプルコードを確認してみましょう。
SELECT
a.no, -- 従業員テーブル.従業員番号
b.department_no, -- 部署テーブル.部署番号
b.department_name, -- 部署テーブル.部署名
a.first_name -- 従業員テーブル.名
FROM
sample1_employees a -- 従業員テーブル 別名a
INNER JOIN
sample1_departments b -- 部署テーブル 別名b
ON
a.department_no = b.department_no
実行結果:
+-------+---------------+-----------------------------+------------+
| no | department_no | department_name | first_name |
+-------+---------------+-----------------------------+------------+
| 10001 | A0001 | アプリ開発部 | 太郎 |
| 10002 | A0001 | アプリ開発部 | 次郎 |
| 10003 | A0002 | データベース開発部 | 花子 |
+-------+---------------+-----------------------------+------------+
このように、テーブル名を指定してSELECTすることができました。次項では、INNER JOINしたテーブルの検索条件を指定する方法について説明します。
結合テーブルの検索条件を指定する
INNER JOINで結合したテーブルに条件をしてするためには、ON句の中でWHERE句の条件指定と同じ書き方で記述します。部署番号に”A0001″(アプリ開発部)の条件を指定するINNER JOIN のサンプルコードを確認してみましょう。
SELECT
a.no, -- 従業員テーブル.従業員番号
b.department_no, -- 部署テーブル.部署番号
b.department_name, -- 部署テーブル.部署名
a.first_name -- 従業員テーブル.名
FROM
sample1_employees a
INNER JOIN
sample1_departments b
ON
a.department_no = b.department_no AND
b.department_no = 'A0001' -- 部署番号がA0001であること
実行結果:
+-------+---------------+--------------------+------------+
| no | department_no | department_name | first_name |
+-------+---------------+--------------------+------------+
| 10001 | A0001 | アプリ開発部 | 太郎 |
| 10002 | A0001 | アプリ開発部 | 次郎 |
+-------+---------------+--------------------+------------+
このように、結合したテーブルに条件を指定することができました。なお、WHERE句については、こちらで詳しく解説していますのでぜひ参考にしてください!
【SQL入門】WHEREで検索条件の指定方法をわかりやすく解説
たくさんのテーブルを結合する方法
INNER JOINはいくつでもテーブル結合することできます。従業員の生年月日テーブルを作成し、
- 従業員テーブル
- 生年月日テーブル
- 部署テーブル
の3つのテーブルを結合するサンプルコードを確認してみましょう。
生年月日テーブル:
CREATE TABLE sample1_birthday (
no int NOT NULL, -- 従業員番号
birthday date,
PRIMARY KEY (no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- テストデータ
INSERT INTO sample1_birthday VALUES('10001','1988-01-01');
INSERT INTO sample1_birthday VALUES('10002','1998-01-01');
INSERT INTO sample1_birthday VALUES('10003','2008-01-01');
INSERT INTO sample1_birthday VALUES('10004','2018-01-01');
3つのテーブルをINNER JOIN するSQLを確認してみます。
SELECT
a.no, -- 従業員テーブル.従業員番号
b.department_no, -- 部署テーブル.部署番号
a.first_name, -- 従業員テーブル.名
c.birthday -- 生年月日テーブル.生年月日
FROM
sample1_employees a -- 従業員テーブル 別名a
INNER JOIN
sample1_departments b -- 部署テーブル 別名b
ON
a.department_no = b.department_no -- 従業員テーブル.部署番号 = 部署テーブル.部署番号
INNER JOIN
sample1_birthday c -- 生年月日テーブル 別名c
ON
c.no = a.no -- 従業員テーブル.従業員番号 = 生年月日テーブル.従業員番号
実行結果:
+-------+---------------+------------+------------+
| no | department_no | first_name | birthday |
+-------+---------------+------------+------------+
| 10001 | A0001 | 太郎 | 1988-01-01 |
| 10002 | A0001 | 次郎 | 1998-01-01 |
| 10003 | A0002 | 花子 | 2008-01-01 |
+-------+---------------+------------+------------+
このように、3つのテーブルを結合することができました。
INNER JOINの使い方を覚えると、関連するテーブルを1回のSQLで結合して検索することが可能になり、複雑になる検索もカンタンに記述できるよになります。