Developer

【SQL基礎】内部結合の基本構文
2021.03.31
Lv1

【SQL基礎】内部結合の基本構文

内部結合とは

内部結合は複数のテーブルから結合条件に一致するレコードのみを結合する方法です。

条件に一致しないレコードは結合されません。

以下はイメージ図です。

もう少し具体的に示したのが以下の図です。

そもそも「結合」というもの自体よくわからないという方はこちらの記事で概要をご確認ください。


内部結合の基本構文

内部結合の基本構文は以下の通りです。

SELECT カラム名
FROM テーブル名
INNER JOIN テーブル名
ON 結合条件;


本記事では例として、以下の3つのテーブルを使用します。

・teachersテーブル
ID、名前、年齢、教科ID、住所IDの5つのカラムで構成されています。

・subjectsテーブル
ID、教科名の2つのカラムで構成されています。

・prefecturesテーブル
ID、都道府県名の2つのカラムで構成されています。


例1.teachersテーブルにsubjectsテーブルを結合する。(全カラムを指定する)

まずはSELECT句で全カラムを指定するケースについて見ていきましょう。

ON句では結合条件を指定します。
今回は、teachersテーブルのsubject_idとsubjectsテーブルのidが一致したら結合するという条件を記述しています。

一点注意するべき箇所があります。
それは、カラム名の前に「テーブル名」と「.(ドット)」を付ける必要があるということです。
(例:teachersテーブルにあるsubject_idカラムの記述方法→”teachers.subject_id”)
扱うテーブルが二つあるため(FROM句とJOIN句)、どちらのテーブルに存在するカラムなのかを明確にする必要があるということです。

SELECT *
FROM teachers
INNER JOIN subjects
ON teachers.subject_id = subjects.id  // "テーブル名.カラム名"でカラム指定


例2.teachersテーブルにsubjectsテーブルを結合する。(特定のカラムを指定する)

例1のように全カラムを取得すると、idに関するカラムが複数存在して見づらくなってしまいます。
例2では、必要なカラムだけ取得します。
先ほどのON句と同様に、SELECT句でも”テーブル名.カラム名”の形で取得したいカラムを指定します。
(teachersテーブルのnameとsubjectsテーブルのnameでカラム名が重複するので、見やすさのために後者にsubjectという別名を付けています。)

SELECT teachers.id, teachers.name, teachers.age, subjects.name AS subject
FROM teachers
INNER JOIN subjects
ON teachers.subject_id = subjects.id;


例3.teachersテーブルにsubjectsテーブルを結合する。(テーブルに別名を付ける)

“テーブル名.カラム名”の書き方は、記述が長くなりやすく手間がかかります。
そこで、テーブルに別名をつけるという方法を紹介します。
カラム名に別名を付けるときと同様に、AS句を用いてテーブルに別名を付けることができます
(AS句は省略可能です。例えば、以下のSQLの”teachers AS T”は”teachers T”と書いても問題ありません。)

SELECT T.id, T.name, T.age, S.name AS subject
FROM teachers AS T       // teachersテーブルにTという別名を付ける
INNER JOIN subjects AS S   // subjectsテーブルにSという別名を付ける
ON T.subject_id = S.id;


例4.teachersテーブルにsubjectsテーブルを結合する。(WHERE句で条件指定する)

結合をする際にも、WHERE句を用いた絞り込みが可能です。
今回の例では年齢が28歳以上という条件で絞り込みを行っています。
例3で表示されていた26歳の”ハジメ”さん以外のレコードが取得されているのがわかります。

SELECT T.id, T.name, T.age, S.name AS subject
FROM teachers AS T
INNER JOIN subjects AS S
ON T.subject_id = S.id
WHERE age >= 28;  // ageカラムの値が28以上


例5.teachersテーブルにsubjectsテーブルとprefecturesテーブルを結合する。

かなり複雑になりますが、三つのテーブルを結合する例も紹介します。
teachersテーブルにsubjectsテーブルを結合したものに対して、prefecturesテーブルを結合するという2段階のステップを踏んでいます。

SELECT T.id, T.name, T.age, S.name AS subject, P.name AS address
FROM (teachers AS T INNER JOIN subjects AS S ON T.subject_id = S.id) // FROM句内でteachersとsubjectsを結合
INNER JOIN prefectures AS P
ON T.address_id = P.id;


学習のポイント

・INNER JOIN句で結合したいテーブルを指定し、ON句で結合条件を指定する。

・カラム名を記述するときにはテーブル名も併せて記述する。

・テーブル名を記述する際には別名を付けると便利である。


練習問題

問題として使用するデータは「SQL練習問題」のものを使用しています。
以下からダウンロード可能です。
また、ダウンロードしたら以下のようにしてworldcup2014データベースを作成し、インポートしてください。
※worldcup2014.zip解凍してできるworldcup2014.sqlファイルをCドライブ直下に配置した場合。

worldcup2014.zip

[sql] CREATE DATABASE worldcup2014;

use worldcup2014

source C:\worldcup2014.sql
[/sql]

問、内部結合を用いて、キックオフ時刻と対戦カードが一度に確認できるようにデータを取得してください。
参考として、pairingsテーブルとcountriesテーブルを以下に示しておきます。(一部省略)

答え

まず、SELECT句にはキックオフ時刻、対戦国①、対戦国②の3つのカラムが必要です。

pairingsテーブルのkickoffカラムとcountriesテーブルのnameカラムが使えそうですね。

次に結合条件を考えましょう。条件として必要なのは以下の2点です。

①pairingsテーブル(別名p)のmy_country_idとcountriesテーブル(別名c1)のidが一致するという条件
p.my_country_id = c1.id

②pairingsテーブル(別名p)のenemy_country_idとcountriesテーブル(別名c2)のidが一致するという条件
p.enemy_country_id = c2.id

今回は、FROM句内で①の条件を満たす内部結合を行った後、②の条件を満たす内部結合を行っています。

SELECT句で指定するカラム名は、”c1.name”、”c2.name”ように、テーブルの別名に対応させる必要があります。

nameカラムが2つ存在する状態になるので、カラムに別名を付けても良いでしょう。

[sql] SELECT p.kickoff, c1.name, c2.name
FROM (pairings p INNER JOIN countries c1 ON p.my_country_id = c1.id)
INNER JOIN countries c2
ON p.enemy_country_id = c2.id;
[/sql]

(実行結果は一部省略)

 

 

連載目次リンク

SQL基礎 連載目次

関連する連載リンク

SQL練習問題 一覧まとめ