内部結合(INNER JOIN句)

広告
eyecatch

2つのテーブルを結合してデータを取得する方法の中で、指定したそれぞれのテーブルのカラムの値が一致するデータだけを取得する方法が内部結合です。ここでは内部結合を行うための INNER JOIN 句の使い方について解説します。

内部結合とは

最初に内部結合について簡単に説明しておきます。内部結合とは2つのテーブルでそれぞれ結合の対象となるカラムを指定し、それぞれのカラムに同じ値が格納されているデータを結合して取得するものです。

次の図を見て下さい。左側のテーブルと右側のテーブルを内部結合します。結合の対象となるカラムは左側のテーブルが「部署ID」、右側のテーブルが「ID」です。この2つのカラムの値が同じデータ同士を結合し取得します。

内部結合とは(1)

左側のテーブルのデータの中で「部署ID」カラムの値が右側のテーブルの「ID」カラムの値の中にない場合にはデータを取得しません。

INNER JOIN句の使い方

SELECT 文と INNER JOIN 句を組み合わせることで2つのテーブルを内部結合させてデータを取得することができます。書式は次の通りです。

SELECT テーブル名.カラム名, ... FROM テーブル名1
  INNER JOIN テーブル名2
  ON テーブル名1.カラム名1 = テーブル名2.カラム名2;

長いので簡略化すると次のようになります。

SELECT (取得するカラム) FROM テーブル名1
  INNER JOIN テーブル名2 ON (結合条件);

SELECT 文で取得するデータは2つのテーブルを結合したものから取得します。取得するカラムはどちらのテーブルにあるどのカラムなのかが分かるように「テーブル名.カラム名」の形式で指定します。

結合条件のところでは結合の対象となるカラムについて「テーブル名1.カラム名1 = テーブル名2.カラム名2」の形式で指定します。

-- --

それでは簡単な例を使ってどのように使用するのかについて確認します。社員の一覧が登録された staff テーブルと、部署が登録された dept テーブルを用意しました。それぞれ INSERT 文を使ってデータを格納してあります。

create table staff(id integer, name text, deptid integer);

insert into staff values(1, 'Suzuki', 1);
insert into staff values(2, 'Endou', 3);
insert into staff values(3, 'Katou', 1);
insert into staff values(4, 'Yamada', 2);
insert into staff values(5, 'Takahashi', 4);
insert into staff values(6, 'Honda', 3);

INNER JOIN句の使い方(1)

create table dept(id integer, name text);

insert into dept values(1, 'Sales');
insert into dept values(2, 'Manage');
insert into dept values(3, 'Dev');

INNER JOIN句の使い方(2)

次にどちらのテーブルにどちらのテーブルを結合するのかを決めます。2つのテーブルを結合を行う場合、どちらのテーブルを先に記述するのかによって結果が少し異なります。今回はstaffテーブルとdeptテーブルを結合しますので次の2通りの記述ができますがどちらでも同じではありません。(どう違ってくるのは後で説明します)。

select * from staff inner join dept on (結合条件);

select * from dept inner join staff on (結合条件);

次に結合条件です。内部結合を行うには2つのテーブルで結合の対象となるカラムを指定します。今回はstaffテーブルの deptid カラムと dept テーブルの id カラムがが対象となります。

select * from staff inner join dept on staff.deptid = dept.id;

では実際に2つのテーブルを内部結合し、データを取得してみます。

select * from staff inner join dept on staff.deptid = dept.id;

INNER JOIN句の使い方(3)

このように内部結合した場合には取得できるデータは2つのテーブルのデータが結合されたものになります。どのようなルールに従って取得するデータが結合されているのかについてはこの後説明します。

データの結合方法に関する解説

先ほどのサンプルを元にどのようにテーブルが内部結合されるのかについて確認していきます。まず SELECT 文の最初に記述されたテーブルの1つ目のデータに対して結合が行われます。

id name      deptid
--------------------
1  Suzuki    1

結合条件は staff.deptid = dept.id です。このデータの deptid の値は 1 ですので、 dept テーブルのデータの中で id カラムの値が 1 のものがあるかどうかを調べます。今回は1つ見つかりました。

id name
------------
1  Sales

見つかった場合にはこの2つのテーブルのデータを結合して1つのデータとして返します。

id name      deptid   id name
-------------------------------
1  Suzuki    1        1  Sales

staffテーブルのデータを順番に同じように結合していきます。

id name      deptid   id name
-------------------------------
1  Suzuki    1        1  Sales
2  Endou     3        3  Dev
3  Katou     1        1  Sales
4  Yamada    2        2  Manage

もし結合条件に一致しないデータがあった場合、内部結合の場合にはそのデータは取得されません。下記のデータの場合、 deptid カラムの値が 4 ですが、 dept テーブルのデータの中には id カラムの値が 4 のものがありませんのでこのデータは取得されません。

id name      deptid
--------------------
5  Takahashi 4

staff テーブルのデータを最後まで同じ手順で結合したら終了です。最終的に取得できるデータは次の通りです。

id name      deptid   id name
-------------------------------
1  Suzuki    1        1  Sales
2  Endou     3        3  Dev
3  Katou     1        1  Sales
4  Yamada    2        2  Manage
6  Honda     3        3  Dev

これは先ほど実際に試した結果と一致します。内部結合の場合には、結合条件に一致しないデータは取得されない点に注意して下さい。

結合が複数のデータで一致する場合

先ほどのサンプルの場合、 staff テーブルの deptid カラムの値と同じ値を持つ dept テーブルのデータが 1 つしかありませんでした。ただ場合によっては複数のデータと一致する場合があります。その場合は一致する全てのデータに対してそれぞれ結合が行われデータを取得します。

それでは実際にどのように結合されるのかを確認してみます。先ほどまでのサンプルとは逆に、 dept テーブルに対して staff テーブルを結合すると次のようなデータを取得することができます。

select * from dept inner join staff on dept.id = staff.deptid;

結合が複数のデータで一致する場合(1)

ではどのようにテーブルが内部結合されるのかについて確認していきます。まず SELECT 文の最初に記述されたテーブルの 1 つ目のデータに対して結合が行われます。

id name
------------
1  Sales

結合条件は dept.id = staff.deptid です。このデータの id の値は 1 ですので、 staff テーブルのデータの中で deptid カラムの値が 1 のものがあるかどうかを調べます。今回は 2 つ見つかりました。

id name      deptid 
--------------------
1  Suzuki    1
3  Katou     1

見つかった 2 つのデータに対してそれぞれ 2 つのテーブルデータを結合して 1 つのデータとして返します。

id name     id name      deptid 
--------------------------------
1 Sales     1  Suzuki    1
1 Sales     3  Katou     1

dept テーブルのデータを順番に同じように結合していきます。

id name     id name      deptid 
----------------------------------
1 Sales     1  Suzuki    1
1 Sales     3  Katou     1
2 Manage    4  Yamada    2
3 Dev       2  Endou     2
3 Dev       6  Honda     6

もし結合条件に一致しないデータがあった場合、内部結合の場合にはそのデータは取得されません。今回はそういったデータはありませんでした。

dept テーブルのデータを最後まで同じ手順で結合したら終了です。最終的に取得できるデータは次の通りです。

id name     id name      deptid 
----------------------------------
1 Sales     1  Suzuki    1
1 Sales     3  Katou     1
2 Manage    4  Yamada    2
3 Dev       2  Endou     2
3 Dev       6  Honda     6

このように結合する時に複数のデータに一致する場合にはそれぞれのデータに対して結合が行われます。

取得するデータのカラム指定方法

SELECT 文では SELECT カラム名1, カラム名2, ・・・ のような記述をしますが、テーブルを結合した場合は1つのデータに複数のデータのカラムが含まれることになります。複数のテーブルで同じカラム名が使用されていることもあるので、テーブルを結合した場合には「カラム名」ではなく「テーブル名.カラム名」のように指定します。

先ほどのサンプルでカラム名を指定せずにデータを取得した場合は次のようになります。

select * from staff inner join dept on staff.deptid = dept.id;

取得するデータのカラム指定方法(1)

取得したデータのカラムには id カラムが 2 つ、 name カラムも 2 つ含まれています。このように複数のテーブルに同じ名前のカラムがある場合にこのカラムをを指定して取得したい場合には次のように「テーブル名.カラム名」の形で指定します。

select staff.id, staff.name, dept.name from staff
  inner join dept on staff.deptid = dept.id;

取得するデータのカラム指定方法(2)

どちらかのテーブルにしか含まれておらずテーブル名を省略してもどちらのテーブルのカラムか分かる場合には「テーブル名.」の部分を省略して「カラム名」だけでも可能です。(下記では deptid カラムがそれに当たります)。

select staff.id, staff.name, deptid, dept.name from staff
  inner join dept on staff.deptid = dept.id;

取得するデータのカラム指定方法(3)

2つのテーブルに同じカラム名があるのにテーブル名を指定せずにカラム名だけを記述した場合は次のような Error: ambiguous column name: カラム名 というエラーとなります。

select name from staff inner join dept on staff.deptid = dept.id;

取得するデータのカラム指定方法(4)

-- --

内部結合を行うための INNER JOIN 句の使い方について解説しました。

SQLite入門の他の記事を見てみる

( Written by Tatsuo Ikura )

関連記事 (一部広告含む)
Profile
profile_img

著者 / TATSUO IKURA

初心者~中級者の方を対象としたプログラミング方法や開発環境の構築の解説を行うサイトの運営を行っています。