<< トップページへ

<< 目次へ

更新日:2013.4.14

複数あるテーブルの紐づけ



 データベース内には複数のテーブルがあり、「キー」となるカラム(多くは顧客番号のようなID)を用いて紐付けを行うことがよくあります。例えば顧客の購買履歴と個人情報のデータはしばしば別のテーブルとして保管されていることが多く、どこのだれが何を買ったのかという情報を得るためには、両者のテーブルを何らかの「キー」によって紐付けを行う必要があるのです。

 もう少し具体的に話を進めるために、以下の2つのテーブルを見てみましょう。左側のテーブルは受験者の情報が入力されており、右側のテーブルは試験に合格した人のIDリストになっています。ここで受験者テーブルから合格者のレコードだけを抽出したい、あるいは受験者テーブルのレコード数はそのままで合格者が誰だかわかるように合格者のIDだけをマージ(列結合)することを考えてみましょう。

ID 年齢 グループ 出身地 得点
001 10 A 群馬 10.223
002 20 A 神奈川 20.345
003 20 C 群馬 30.321
004 40 B 東京 10.894
005 30 B 東京 50.009
006 10 C 東京 40.332
007 50 A 埼玉 10.501
008 30 B 神奈川 40.444
009 20 A 埼玉 40.441
010 60 A 東京 20.004
受験者テーブル.csv
ID
003
005
006
008
009
合格者リスト.csv


■JOIN 基本構文

 複数のテーブルをある「キー」項目によって紐づけるためにはJOIN構文を利用する。正確にはINNER JOIN(内部結合)、LEFT JOIN(左部結合)、RIGHT JOIN(右部結合)がある。

 
## 内部結合の基本構文
select * from [結合基テーブル] INNER JOIN [結合先テーブル] ON 
   結合基テーブル.カラム名=結合先テーブル.カラム名;

## 左部結合の基本構文
select * from [結合基テーブル] LEFT JOIN [結合先テーブル] ON 
   結合基テーブル.カラム名=結合先テーブル.カラム名;

## 右部結合の基本構文
select * from [結合基テーブル] RIGHT JOIN [結合先テーブル] ON 
   結合基テーブル.カラム名=結合先テーブル.カラム名;
 


■テーブルjyukenとテーブルgoukakuを内部結合する

 内部結合(INNER JOIN)の場合、両テーブルでキーとなるカラム(この場合はID)が一致するものだけ抽出される。どちらか一方にしか存在しないIDに該当するレコードは削除される(表示されない)。

【注意】
環境によっては、1つのテーブルに同じカラムが存在することが許されないので、その場合はカラム名を変更して表示させる必要がある。以下の例だと[id]というカラムが同時に存在しているが、これが許されずエラーが出てしまうことがある(SQLのバージョンに要注意)。

 
select * from jyuken inner join goukaku on 
   jyuken.id=goukaku.id;


# ーーーーー 【実行例】
mysql> select * from jyuken inner join goukaku on
    ->  jyuken.id=goukaku.id;
+------+------+------+--------+--------+------+
| id   | age  | grp  | area   | score  | id   |
+------+------+------+--------+--------+------+
| 003  |   20 | C    | 群馬   | 30.321 | 003  | ←内部結合の場合は紐付く
| 005  |   30 | B    | 東京   | 50.009 | 005  |  レコードだけが表示される
| 006  |   10 | C    | 東京   | 40.332 | 006  |
| 008  |   30 | B    | 神奈川 | 40.444 | 008  |
| 009  |   20 | A    | 埼玉   | 40.441 | 009  |
+------+------+------+--------+--------+------+
 


■テーブルjyukenとテーブルgoukakuを外部結合(左部結合)する

 外部結合(以下の例はLEFT JOIN)の場合、基となるテーブル(以下の例はjyuken)は全て表示される。

 
select * from jyuken left join goukaku on 
 jyuken.id=goukaku.id;


# ーーーーー 【実行例】
mysql> select * from jyuken left join goukaku on
    ->  jyuken.id=goukaku.id;
+------+------+------+--------+--------+------+
| id   | age  | grp  | area   | score  | id   |
+------+------+------+--------+--------+------+
| 001  |   10 | A    | 群馬   | 10.223 | NULL | ←外部結合の場合は
| 002  |   20 | A    | 神奈川 | 20.345 | NULL |  基となるテーブルは全て
| 003  |   20 | C    | 群馬   | 30.321 | 003  |  表示される
| 004  |   40 | B    | 東京   | 10.894 | NULL |
| 005  |   30 | B    | 東京   | 50.009 | 005  |
| 006  |   10 | C    | 東京   | 40.332 | 006  |
| 007  |   50 | A    | 埼玉   | 10.501 | NULL |
| 008  |   30 | B    | 神奈川 | 40.444 | 008  |
| 009  |   20 | A    | 埼玉   | 40.441 | 009  |
| 010  |   60 | A    | 東京   | 20.004 | NULL |
+------+------+------+--------+--------+------+
 


■jyuken、goukaku、nenreiについてjyukenを結合基テーブルとして紐づけする

 ここで新たに年齢区分のマスタテーブルを追加して、3つのテーブルを紐付けすることを考えてみる。とにかく受験者テーブルに対して、他のテーブルのすべてのカラムを紐付けるためには、単にLEFT JOINで複数のテーブルを指定してやるだけでよい。ここで表示させるカラムを制御したい場合は SELECT * FROM の部分で * のかわりに任意のカラム名だけを明記すればよい。

年齢 年齢区分
10 ジュニア
20 ジュニア
30 ミドル
40 ミドル
50 ミドル
60 シニア
70 シニア
80 シニア
90 シニア
年齢区分マスタ.csv
 
# 全てのカラムを表示させる
select * from jyuken 
   left join goukaku on jyuken.id=goukaku.id
   left join nenrei on jyuken.age=nenrei.age;


# ーーーーー 【実行例】
mysql> select * from jyuken
    ->  left join goukaku on jyuken.id=goukaku.id
    ->  left join nenrei on jyuken.age=nenrei.age;
+------+------+------+--------+--------+------+------+----------+
| id   | age  | grp  | area   | score  | id   | age  | kubun    |
+------+------+------+--------+--------+------+------+----------+
| 001  |   10 | A    | 群馬   | 10.223 | NULL |   10 | ジュニア |
| 002  |   20 | A    | 神奈川 | 20.345 | NULL |   20 | ジュニア |
| 003  |   20 | C    | 群馬   | 30.321 | 003  |   20 | ジュニア |
| 004  |   40 | B    | 東京   | 10.894 | NULL |   40 | ミドル   |
| 005  |   30 | B    | 東京   | 50.009 | 005  |   30 | ミドル   |
| 006  |   10 | C    | 東京   | 40.332 | 006  |   10 | ジュニア |
| 007  |   50 | A    | 埼玉   | 10.501 | NULL |   50 | ミドル   |
| 008  |   30 | B    | 神奈川 | 40.444 | 008  |   30 | ミドル   |
| 009  |   20 | A    | 埼玉   | 40.441 | 009  |   20 | ジュニア |
| 010  |   60 | A    | 東京   | 20.004 | NULL |   60 | シニア   |
+------+------+------+--------+--------+------+------+----------+



# 任意のカラムだけを表示させる
select jyuken.id, jyuken.grp, goukaku.id, nenrei.kubun from jyuken 
   left join goukaku on jyuken.id=goukaku.id
   left join nenrei on jyuken.age=nenrei.age;


# ーーーーー 【実行例】
mysql> select jyuken.id, jyuken.grp, goukaku.id, nenrei.kubun from jyuken
    ->  left join goukaku on jyuken.id=goukaku.id
    ->  left join nenrei on jyuken.age=nenrei.age;
+------+------+------+----------+
| id   | grp  | id   | kubun    |
+------+------+------+----------+
| 001  | A    | NULL | ジュニア |
| 002  | A    | NULL | ジュニア |
| 003  | C    | 003  | ジュニア |
| 004  | B    | NULL | ミドル   |
| 005  | B    | 005  | ミドル   |
| 006  | C    | 006  | ジュニア |
| 007  | A    | NULL | ミドル   |
| 008  | B    | 008  | ミドル   |
| 009  | A    | 009  | ジュニア |
| 010  | A    | NULL | シニア   |
+------+------+------+----------+