テーブルの結合

結合の種類

続いて、データベースにおける複数のテーブルの結合の方法を紹介します。SELECT文を用いると、複数のテーブルを結合することができるのです。どのようにテーブルを結合し取得するデータは何になるのかによって内部結合外部結合交差結合の3種類の方式が用意されています。

以下、それぞれの接続と、その内容について説明していきますが、ここでは、内部結合および交差結合について説明していくことにします。

内部結合

内部結合とは

データベースでは、複数のテーブルを結合して検索するという処理を行うことがよくあります。

そのなかで、最も使用頻度が高いのが、内部結合(ないぶけつごう)です。内部結合はそれぞれのテーブルの指定した列の値が一致するデータだけを取得します。基本となる構文は次の通りです。

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

結合の対象となるテーブルをFROMの後とINNER JOINの後に指定します。そしてONの後に結合するカラムをイコール(=)で結んで指定します。

内部結合ではテーブルとテーブルを結合した結果を取得します。結合はそれぞれのテーブルの指定したカラムの値が同じものを1つのデータとして取得します。2つのテーブルで同じ値が存在しないデータは取得されません。

テーブルの追加

具体的な例で見てみます。最初に、データベースschoolに、以下の構造を持ったclass_nameテーブルを作成し、追加しましょう。(表6-1.~6-2.)

表6-1.テーブルclass_name
項目列名データ型属性
分類classchar(4)NOT NULL(空白を許さない)
名前pricevarchar(10)NOT NULL(空白を許さない)

このテーブルには次のようなデータが格納されているとします。

表6-2.テーブルclass_nameに挿入するデータ
classname
text教科書
mdvdマルチメディアDVD
sftwソフトウェア
sbtx副読本
pbbk問題集
dict辞書
compコンピューター

このデータは、同じくデータベースにあるschool内にあるresourceにある、class(分類)の名前を日本語で表記したものです。resourceテーブルには、分類コードとしてしか登録されていませんが、この表には、分類コードの内訳が日本語で記述されています。

Sample601.sql
#class_nameテーブルの生成
CREATE TABLE class_name(
    class       char(4) NOT NULL,
    name        varchar(10) NOT NULL
);

#データの挿入
INSERT INTO class_name VALUES('text','教科書');
INSERT INTO class_name VALUES('mdvd','マルチメディアDVD');
INSERT INTO class_name VALUES('sftw','ソフトウェア');
INSERT INTO class_name VALUES('sbtx','副読本');
INSERT INTO class_name VALUES('pbbk','問題集');
INSERT INTO class_name VALUES('dict','辞書');
INSERT INTO class_name VALUES('comp','コンピューター');

これを、resourceテーブルを見るだけでは、各教材の分類が分かりづらいので、内部結合を利用して、この二つのテーブルを結合し、よりわかりやすくしてみましょう。

以上のテーブルの生成、およびデータの挿入をSQL文で表すと、以下のようになります。検索をする前にまずは準備しておきましょう。

内部結合の基本

内部結合を行うには、2つのテーブルで結合の対象となるカラムを指定します。例えば次のように指定します。

Sample602.sql
SELECT * FROM resource INNER JOIN class_name ON resource.class = class_name.class;

実行結果は、以下のようになります。(図6-1.)

図6-1.単純な内部結合
単純な内部結合

この場合、resourceテーブルのclassカラムとclass_nameテーブルのclassカラムを使って結合します。データの取得は次のように行われます。

まずresourceテーブルの最初のデータのclassカラムの値に対して、class_nameテーブルのclassカラムの中に同じ値があるかどうかを調べます。存在した場合はresourceテーブルのデータとclass_nameテーブルの一致したデータと結合させてまとめて一つのデータとして取得します。(図6-2.参照)

図6-2.内部結合のイメージ
内部結合のイメージ

ただし、resourceテーブルのclassカラムの中には、class_nameテーブルのclassカラムにある、「comp」は存在しません。そのため、一致する条件が成り立たないことから、「comp」の行は、検索結果には現れません

結合されたデータには各テーブルに存在していたカラムが全て含まれることになります。結合された全データの中で、どのカラムを取得するかはSELECT文の後ろで指定します。カラムは「テーブル名.カラム名」の形式で指定します。

なお、resourceテーブルおよび、class_nameテーブルを結合するのに利用されるカラムはともに、「class」であり、同一名であることから、こういった場合は、sql文を以下のように書き換えることが可能です。

Sample603.sql
SELECT * FROM resource INNER JOIN class_name USING(class);

USINGの()内に、共通のカラム名を入れることにより、同様の検索結果を得ることが可能です。ただし、この場合、共通のカラムである、「class」が先頭にきます。(図6-3.)

図6-3.USINGでの内部結合の結果
USINGでの内部結合の結果

USINGを使った内部結合の正式な書式は以下のようになります。

USINGの入った内部結合
SELECT * FROM テーブル1 INNER JOIN テーブル2 USING ( 列名 )

様々な検索方法

では、この内部結合を利用して、resourceテーブルをよりわかりやすい形で検索してみましょう。以下のsql文を実行してみてください。

Sample604.sql
SELECT code,resource.name,price,class_name.name FROM resource INNER JOIN class_name USING(class);

実行結果は以下のようになります。(図6-4.)

図6-4.resourceテーブルをよりわかりやすい形で検索
resourceテーブルをよりわかりやすい形で検索

これにより、データはだいぶん分かりやすくなりました。classにあった記号が、具体的なカテゴリー名になり、意味が分かりやすくなっています。

一般的なSELECT文の場合と同様、内部結合で特定のカラムを表示する場合は、カラム名を入れます。しかし、このケースは、「name」カラムという同一の名前のカラムが両方のテーブルに存在します。そういった場合は、このサンプルのように「テーブル名.カラム名」として指定して区別します。

具体的に説明すると、resource.nameであれば、resourceテーブルのnameカラム、class_name.nameであれば、class_nameテーブルのnameカラムが表示されます。

また、一つのテーブルの検索で用いた、WHEREによる条件検索をすることも可能です。以下のSQL文を実行してみてください。

Sample605.sql
SELECT code,resource.name,price,class_name.name FROM resource INNER JOIN class_name 
USING(class) WHERE price >= 3000;

Sample604.sqlの例から、さらにpriceが3000以上のものが表示されました。(図6-5.)このように、複数のテーブルを結合したものを、さらに様々な条件をつけて検索することも可能です。

図6-5.内部結合とWHERE句
内部結合とWHERE句

WHERE以外の、さまざまな検索方法が内部結合を行った場合でも利用できるのは言うまでもありません。

交差結合

交差結合とは

次に、交差結合について説明します。交差結合(こうさけつごう)とは、二つのテーブルの組み合わせのすべての組み合わせを作る結合で、クロス結合とも呼ばれます。書式は以下の通りです。

交差結合の書式
SELECT * FROM テーブル1 CROSS JOIN テーブル2;

では、実際に、resourceテーブルとclass_nameテーブルを交差結合するとします。すると、sql文は以下のようになります。

Sample606.sql
SELECT * FROM resource CROSS JOIN class_name;

この実行結果は、以下のようになります。(図6-6.)結果からみるとわかるとおり、二つのテーブルの列の組み合わせが全て出力されていることがわかります。

図6-6.交差結合
交差結合

resourceテーブルが10行、class_nameテーブルが7行あることから、このデータの組み合わせは、7×10=70行あります。ここには、それぞれのテーブルの各行のすべての組み合わせが出力されます。

検索結果の絞り込み

二つのテーブルのすべての組み合わせが出ることがわかります。他の結合同様、WHEREをつけて条件の絞込みをすることも可能です。

Sample607.sql
SELECT * FROM resource CROSS JOIN class_name WHERE resource.class = class_name.class;

この検索は、交差結合したresourceとclass_nameテーブルの中から、それぞれのテーブルのclassカラムが一致するもののみを表示したものです。そのため、結果は、図6-1.と同じになるので省略します。

交差結合の問題点

交差結合の問題点は、テーブル間のすべての行の組み合わせを表示するため、結果が某大になることです。そのため、使い方を誤ると、データベースの検索スピードのパフォーマンスが著しく低下する可能性があります。

そのため、ほとんどの場合、複数のテーブルを結合する場合は、ここで紹介した内部結合と、次に紹介する外部結合のどちらかを使うの場合がほとんどです。