技術コンテンツ

【MySQL】内部結合(INNER JOIN) - テーブル結合

【MySQL】内部結合(INNER JOIN) - テーブル結合

MySQLの内部結合について解説します。

検証環境

内部結合

内部結合は“複数テーブルを繋げて1つの表データを作成すること”です。

各テーブルのカラムについて、値が同じレコード同士を繋げます。

次のshopsテーブルとitemsテーブルで具体例を示します。

/* shopsテーブル */
+----+--------------+
| id | name         |
+----+--------------+
|  1 | Fruits Shop  |
|  2 | Food Shop    |
|  3 | Dessert Shop |
+----+--------------+

/* itemsテーブル */
+----+-----------+-------+-------+---------+
| id | name      | price | stock | shop_id |
+----+-----------+-------+-------+---------+
|  1 | Apple     |   200 |    10 |       1 |
|  2 | Orange    |   150 |     3 |       1 |
|  3 | Pineapple |  1100 |     3 |       2 |
|  4 | Grapes    |  3500 |     1 |       2 |
+----+-----------+-------+-------+---------+

itemsテーブルはshop_idカラムでshopsテーブルのidカラムの値を保持します。

この2カラムで内部結合した結果は次の表です。

+----+-------------+----+-----------+-------+-------+---------+
| id | name        | id | name      | price | stock | shop_id |
+----+-------------+----+-----------+-------+-------+---------+
|  1 | Fruits Shop |  1 | Apple     |   200 |    10 |       1 |
|  1 | Fruits Shop |  2 | Orange    |   150 |     3 |       1 |
|  2 | Food Shop   |  3 | Pineapple |  1100 |     3 |       2 |
|  2 | Food Shop   |  4 | Grapes    |  3500 |     1 |       2 |
+----+-------------+----+-----------+-------+-------+---------+

各テーブルのレコードが2カラムを基点に結合されています。

また、内部結合は結合しなかったレコードを除外します。

そのため、shopsテーブルのid3のレコードは、itemsテーブルのshop_idカラムに存在せず、表示されません。

INNER JOIN

MySQLで内部結合を実現するにはINNER JOIN句を使用します。

基本構文

SELECT 表示カラム FROM テーブルA INNER JOIN テーブルB ON テーブルA.カラム = テーブルB.カラム

INNER JOIN句はSELECT文と合わせて使用します。

INNER JOIN テーブルB ON テーブルA.カラム = テーブルB.カラムがINNER JOIN句の部分です。

SELECT文のテーブルAに対して内部結合するテーブルBと、結合の基点となる各カラムをテーブルA.カラムテーブルB.カラムの形式で記述します。

サンプル

mysql> SELECT * FROM shops;
+----+--------------+
| id | name         |
+----+--------------+
|  1 | Fruits Shop  |
|  2 | Food Shop    |
|  3 | Dessert Shop |
+----+--------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM items;
+----+-----------+-------+-------+---------+
| id | name      | price | stock | shop_id |
+----+-----------+-------+-------+---------+
|  1 | Apple     |   200 |    10 |       1 |
|  2 | Orange    |   150 |     3 |       1 |
|  3 | Pineapple |  1100 |     3 |       2 |
|  4 | Grapes    |  3500 |     1 |       2 |
+----+-----------+-------+-------+---------+
4 rows in set (0.01 sec)

mysql> SELECT * FROM shops
    ___ih_hl_start
    -> INNER JOIN items ON shops.id = items.shop_id;
    ___ih_hl_end
+----+-------------+----+-----------+-------+-------+---------+
| id | name        | id | name      | price | stock | shop_id |
+----+-------------+----+-----------+-------+-------+---------+
|  1 | Fruits Shop |  1 | Apple     |   200 |    10 |       1 |
|  1 | Fruits Shop |  2 | Orange    |   150 |     3 |       1 |
|  2 | Food Shop   |  3 | Pineapple |  1100 |     3 |       2 |
|  2 | Food Shop   |  4 | Grapes    |  3500 |     1 |       2 |
+----+-------------+----+-----------+-------+-------+---------+
4 rows in set (0.00 sec)

23行目が内部結合(INNER JOIN句)の部分です。

shopsテーブルのidカラムとitemsテーブルのshop_idカラムが同じ値のレコードを結合しています。

上記サンプルでは*によって全てのカラムを表示していますが、通常のSELECT文と同様に任意のカラムのみ表示することも可能です。

2つのテーブルでカラム名が重複している場合は、どちらのテーブルのカラムか分かるようにテーブル名とカラム名をドット(.)で繋げ、テーブル名.カラム名のように明示的に記述します。

mysql> SELECT shops.name, items.name, price, stock FROM shops
    -> INNER JOIN items ON shops.id = items.shop_id;
+-------------+-----------+-------+-------+
| name        | name      | price | stock |
+-------------+-----------+-------+-------+
| Fruits Shop | Apple     |   200 |    10 |
| Fruits Shop | Orange    |   150 |     3 |
| Food Shop   | Pineapple |  1100 |     3 |
| Food Shop   | Grapes    |  3500 |     1 |
+-------------+-----------+-------+-------+
4 rows in set (0.00 sec)