【SQL】INNER JOIN(内部結合)を3分でわかりやすく解説

Database

INNER JOIN(内部結合)は、テーブルとテーブルを結合するためのSQL文です。

INNER JOIN わかりやすく
図1:テーブル結合
SELECT A.ID, A.Name, A.Class, A.Japanese, A.Math, A.English, B.Science, B.SocialStudies
FROM PointList AS A
INNER JOIN SubPointList AS B
ON A.ID = B.ID;

/* 結果
+----+------+-------+----------+------+---------+---------+---------------+
| ID | Name | Class | Japanese | Math | English | Science | SocialStudies |
+----+------+-------+----------+------+---------+---------+---------------+
|  1 | 佐藤 | A     |      100 |  100 |      85 |      90 |            75 |
|  2 | 鈴木 | A     |       90 |   70 |      70 |      90 |            70 |
|  3 | 高橋 | A     |       85 |   70 |      65 |      85 |            70 |
|  4 | 中村 | A     |       90 |   65 |      85 |      40 |             0 |
+----+------+-------+----------+------+---------+---------+---------------+
*/

複数のテーブルからほしい情報を取得し、1つの結果として表示したい場合に用います。

テーブル結合には大きく分類すると内部結合と外部結合―。2種類の結合パターンが存在しますが、本ページでは内部結合(INNER JOIN)について解説しています。

内部結合/外部結合
  • 内部結合:両方のテーブルに存在するキーを条件に結合
  • 外部結合:1つのテーブルを基準として結合

このページではSQL初心者向けにCASE文の利用方法をわかりやすく丁寧に図解付き・サンプルコード付きで解説します。

このページで学べる内容
  • 【前提】テーブル結合とは?
  • INNER JOIN(内部結合)とは
    • INNER JOIN の構文ルール
    • INNER JOIN のサンプルコード/注意点

データベースエンジニアを目指す方であれば知らないと恥ずかしい超・基本知識です。是非最後までご覧ください。

スポンサーリンク

INNER JOIN:内部結合とは?

INNER JOIN わかりやすく
図1:テーブル結合

INNER JOIN(内部結合)はテーブルとテーブルを結合する際に用います。

1つのテーブルだけでは情報が不足しているような場合に、他のテーブルのデータの情報も併せて表示したい場合などに用います。

INNER JOIN わかりやすく

早速構文ルールを確認していきます。

INNER JOIN:構文ルール

SQL:INNER JOIN
SELECT
  A.カラム名, B.カラム名
FROM
  テーブルA
INNER JOIN
  テーブルB
ON
  A.結合キー = B.結合キー;
  • FROM句:INNER JOINで結合対象のテーブルを記述
  • ON句:結合キーを記述

結合キーは、テーブルとテーブルを結合する際の基準となるカラムのことです。

例えば以下2つのテーブルを結合する際に「役職ID」を基準にする場合、この「役職ID」が結合キーです。

INNER JOIN 内部結合

今回は実際にサンプルとなるテーブルを用意し、どのようにINNER JOIN(内部結合)の処理が行われるか?を確認していきましょう。

INNER JOIN 内部結合
図2:サンプルテーブル

実際に自分で動かしてみたいという方のために、テーブルのCREATE文とレコード登録のためのINSERT文を掲載しておきます。

テーブル定義:参考(CREATE TABLE

-- テーブルA
CREATE TABLE PointList (
ID       INT(3)       NOT NULL PRIMARY KEY,
Name     VARCHAR(50)  NOT NULL,
Class    VARCHAR(1),
Japanese INT(3)       DEFAULT '0',
Math     INT(3)       DEFAULT '0', 
English  INT(3)       DEFAULT '0'
);

/*
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| ID       | int(3)      | NO   | PRI | NULL    |       |
| Name     | varchar(50) | NO   |     | NULL    |       |
| Class    | varchar(1)  | YES  |     | NULL    |       |
| Japanese | int(3)      | YES  |     | 0       |       |
| Math     | int(3)      | YES  |     | 0       |       |
| English  | int(3)      | YES  |     | 0       |       |
+----------+-------------+------+-----+---------+-------+
*/

-- テーブルB
CREATE TABLE SubPointList (
ID             INT(3)       NOT NULL PRIMARY KEY,
Name           VARCHAR(50)  NOT NULL,
Class          VARCHAR(1),
Science        INT(3)       DEFAULT '0',
SocialStudies  INT(3)       DEFAULT '0'
);

/*
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| ID            | int(3)      | NO   | PRI | NULL    |       |
| Name          | varchar(50) | NO   |     | NULL    |       |
| Class         | varchar(1)  | YES  |     | NULL    |       |
| Science       | int(3)      | YES  |     | 0       |       |
| SocialStudies | int(3)      | YES  |     | 0       |       |
+---------------+-------------+------+-----+---------+-------+
*/

利用するダミーレコード:参考(INSERT文

INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (1,'佐藤','A',100,100,85);
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (2,'鈴木','A',90,70,70);
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (3,'高橋','A',85,70,65);
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (4,'中村','A',90,65,85);
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (5,'小林','B',70,90,65);
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (6,'山口','B',90,85,85);
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (7,'田中','B',70,90,65);
INSERT INTO PointList (ID,Name,Class,Japanese,Math,English) VALUES (8,'伊藤','B',70,90,65);

-- テーブルA確認
SELECT * FROM PointList;
/*
+----+------+-------+----------+------+---------+
| ID | Name | Class | Japanese | Math | English |
+----+------+-------+----------+------+---------+
|  1 | 佐藤 | A     |      100 |  100 |      85 |
|  2 | 鈴木 | A     |       90 |   70 |      70 |
|  3 | 高橋 | A     |       85 |   70 |      65 |
|  4 | 中村 | A     |       90 |   65 |      85 |
|  5 | 小林 | B     |       70 |   90 |      65 |
|  6 | 山口 | B     |       90 |   85 |      85 |
|  7 | 田中 | B     |       70 |   90 |      65 |
|  8 | 伊藤 | B     |       70 |   90 |      65 |
+----+------+-------+----------+------+---------+
*/

INSERT INTO SubPointList (ID,Name,Class,Science,SocialStudies) VALUES (1,'佐藤','A',90,75);
INSERT INTO SubPointList (ID,Name,Class,Science,SocialStudies) VALUES (2,'鈴木','A',90,70);
INSERT INTO SubPointList (ID,Name,Class,Science,SocialStudies) VALUES (3,'高橋','A',85,70);
INSERT INTO SubPointList (ID,Name,Class,Science,SocialStudies) VALUES (4,'中村','A',40,0);

-- テーブルB確認
SELECT * FROM SubPointList;
+----+------+-------+---------+---------------+
| ID | Name | Class | Science | SocialStudies |
+----+------+-------+---------+---------------+
|  1 | 佐藤 | A     |      90 |            75 |
|  2 | 鈴木 | A     |      90 |            70 |
|  3 | 高橋 | A     |      85 |            70 |
|  4 | 中村 | A     |      40 |             0 |
+----+------+-------+---------+---------------+

INNER JOIN:サンプルコード

2つのテーブルを "ID列" を結合キーとしてINNER JOIN(内部結合)した結果がこちらです。

SELECT
  A.ID, A.Name, A.Class, A.Japanese, A.Math, A.English, B.Science, B.SocialStudies
FROM
  PointList AS A
INNER JOIN
  SubPointList AS B
ON
  A.ID = B.ID;

/* 結果
+----+------+-------+----------+------+---------+---------+---------------+
| ID | Name | Class | Japanese | Math | English | Science | SocialStudies |
+----+------+-------+----------+------+---------+---------+---------------+
|  1 | 佐藤 | A     |      100 |  100 |      85 |      90 |            75 |
|  2 | 鈴木 | A     |       90 |   70 |      70 |      90 |            70 |
|  3 | 高橋 | A     |       85 |   70 |      65 |      85 |            70 |
|  4 | 中村 | A     |       90 |   65 |      85 |      40 |             0 |
+----+------+-------+----------+------+---------+---------+---------------+
*/
INNER JOIN 内部結合
図3:INNER JOINのイメージ

内部結合のポイントは大きく2つ。

INNER JOIN(内部結合)のポイント
  • 両方のテーブルに結合キーが存在する場合のみ結合される
  • SELECT句では 「テーブル名.カラム名」 の形で記述

内部結合のポイント①:結合キーが両テーブルに存在する場合のみ出力

INNER JOIN(内部結合)では、ON句指定した結合キーが両方のテーブルに存在する場合にのみ結合が行われるということがポイントの1つ目。

INNER JOIN 内部結合

わかりやすく示すと、以下の図でいえば両方のテーブルにある「役職A」と「役職B」のレコードのみが結合されるということです。

指定した結合キーが両方のテーブルに存在する場合にのみ結合が行われるというのが内部結合と外部結合の一番の違いです。

内部結合/外部結合
  • 内部結合:両方のテーブルに存在するキーを条件に結合
  • 外部結合:1つのテーブルを基準として結合

※それ以外の構文ルールはほとんど同じです。

内部結合のポイント②:SELECT句は「テーブル名.カラム名」の形で記述

先ほどのSQL文のSELECT句をもう一度確認してみましょう。

SELECT
  A.ID, A.Name, A.Class, A.Japanese, A.Math, A.English, B.Science, B.SocialStudies
FROM
  PointList AS A
INNER JOIN
  SubPointList AS B
ON
  A.ID = B.ID;

「テーブル名.カラム名」の形で記述していることが分かります。

これは、両方のテーブルに同じカラム名(例 ID,Name,Class)が存在しているため、その記述の曖昧さを避けるための措置です。(=どちらのテーブルのカラム名を表示すればよいか?をシステムが判断することができなくなってしまう。

-- ID,Name,Classは結合対象の両方のテーブルに含まれるためエラーになる
SELECT
  ID,Name,Class,Japanese,Science
FROM
  PointList
INNER JOIN
  SubpointList
ON
  PointList.ID = SubpointList.ID;

-- ERROR 1052 (23000): Column 'ID' in field list is ambiguous

したがって、片方のテーブルのみに存在するレコードを利用する場合は、厳密に「テーブル名.カラム名」の形で記述する必要はありません。

ただし、JOINを用いる場合には、SQLを読みやすくするために基本的に「テーブル名.カラム名」の形で記述することが一般的です。

*を利用するパターン

SELECT句にワイルドカード「*」を利用すると以下のように両方のテーブルに存在するすべてのカラムが取得対象となります。

SELECT
  *
FROM
  PointList AS A
INNER JOIN
  SubPointList AS B
ON
  A.ID = B.ID;

/* 結果→全カラムがそのまま表示される
+----+------+-------+----------+------+---------+----+------+-------+---------+---------------+
| ID | Name | Class | Japanese | Math | English | ID | Name | Class | Science | SocialStudies |
+----+------+-------+----------+------+---------+----+------+-------+---------+---------------+
|  1 | 佐藤 | A     |      100 |  100 |      85 |  1 | 佐藤 | A     |      90 |            75 |
|  2 | 鈴木 | A     |       90 |   70 |      70 |  2 | 鈴木 | A     |      90 |            70 |
|  3 | 高橋 | A     |       85 |   70 |      65 |  3 | 高橋 | A     |      85 |            70 |
|  4 | 中村 | A     |       90 |   65 |      85 |  4 | 中村 | A     |      40 |             0 |
+----+------+-------+----------+------+---------+----+------+-------+---------+---------------+
*/
INNER JOIN(内部結合)のまとめ
  • テーブルとテーブルを結合させる際に利用する
  • 両方のテーブルに結合キーが存在する場合のみ結合
  • SELECT句では 「テーブル名.カラム名」 の形で記述する
INNER JOIN 内部結合
SELECT
  A.ID, A.Name, A.Class, A.Japanese, A.Math, A.English, B.Science, B.SocialStudies
FROM
  PointList AS A
INNER JOIN
  SubPointList AS B
ON
  A.ID = B.ID;

システムエンジニアを目指したい方は

システムエンジニアを目指す方や、IT知識を1から身につけたい方は以下のページをご覧ください。

正直どこから学び始めればよいかわからない。どのように勉強していけば、エンジニアとしてのスキルが磨けるか?が分からない・・・という方は必見です。

タイトルとURLをコピーしました