<< 目次へ
更新日:2013.4.14
複数あるテーブルの紐づけ
データベース内には複数のテーブルがあり、「キー」となるカラム(多くは顧客番号のようなID)を用いて紐付けを行うことがよくあります。例えば顧客の購買履歴と個人情報のデータはしばしば別のテーブルとして保管されていることが多く、どこのだれが何を買ったのかという情報を得るためには、両者のテーブルを何らかの「キー」によって紐付けを行う必要があるのです。
もう少し具体的に話を進めるために、以下の2つのテーブルを見てみましょう。左側のテーブルは受験者の情報が入力されており、右側のテーブルは試験に合格した人のIDリストになっています。ここで受験者テーブルから合格者のレコードだけを抽出したい、あるいは受験者テーブルのレコード数はそのままで合格者が誰だかわかるように合格者のIDだけをマージ(列結合)することを考えてみましょう。
|
|
■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 | シニア |
# 全てのカラムを表示させる 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 | シニア | +------+------+------+----------+