SQL 結合(JOIN)
SQL JOIN は、2つ以上のテーブルの行を結合するために使用されます。
下図は、LEFT JOIN、RIGHT JOIN、INNER JOIN、OUTER JOIN に関連する7つの使い方を示しています。
| 種類 | 説明 |
|---|---|
| INNER JOIN | 2つのテーブルで結合条件を満たすレコードを返します(交差)。 |
| LEFT JOIN | 右テーブルに一致するレコードがない場合でも、左テーブルのすべてのレコードを返します(左テーブルを保持)。 |
| RIGHT JOIN | 左テーブルに一致するレコードがない場合でも、右テーブルのすべてのレコードを返します(右テーブルを保持)。 |
| FULL OUTER JOIN | 2つのテーブルの和集合を返し、一致するレコードと一致しないレコードの両方を含みます。 |
| CROSS JOIN | 2つのテーブルのデカルト積を返し、左テーブルの各レコードと右テーブルの各レコードを組み合わせます。 |
| SELF JOIN | テーブルをそれ自身と結合します。 |
| NATURAL JOIN | 同名のフィールドに基づいて自動的にマッチングして結合するテーブル。 |
サンプルデータ
表1:Customers
| CustomerID | Name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
表2:Orders
| OrderID | CustomerID | Product |
|---|---|---|
| 101 | 1 | Laptop |
| 102 | 2 | Phone |
| 103 | 4 | Tablet |
各結合結果の比較
| JOIN の種類 | 結果 |
|---|---|
| INNER JOIN | 2つのテーブルで一致するレコードを返します。この例では、CustomerID が 1 と 2 のレコードのみが両方のテーブルで一致するため、これらのレコードだけが返されます。 |
| LEFT JOIN | 右テーブル(Orders)に一致するレコードがない場合でも、左テーブル(Customers)のすべてのレコードを返します。左テーブルで一致しない右テーブルのレコードについては、結果の右テーブルのフィールドは NULL になります。この例では、CustomerID が 3 のレコードは右テーブルに一致しないため、対応する Product は NULL になります。 |
| RIGHT JOIN | 左テーブル(Customers)に一致するレコードがない場合でも、右テーブル(Orders)のすべてのレコードを返します。右テーブルで一致しない左テーブルのレコードについては、結果の左テーブルのフィールドは NULL になります。この例では、OrderID が 103 のレコードは左テーブルに一致しないため、対応する Name は NULL になります。 |
| FULL OUTER JOIN | 一致するかどうかに関係なく、2つのテーブルのすべてのレコードを返します。どちらかのテーブルに一致するレコードがない場合、そのテーブルのフィールドは NULL になります。この例では、CustomerID が 3 のレコードと OrderID が 103 のレコードは、それぞれ相手のテーブルでは NULL として表示されます。 |
| CROSS JOIN | 2つのテーブルのデカルト積を返します。つまり、左テーブルの各行と右テーブルの各行を組み合わせます。この例では、各顧客が各注文と組み合わされ、複数の結果が生成されます。 |
| SELF JOIN | テーブルをそれ自身と結合します。これは通常、従業員とそのマネージャーの関係など、テーブル内の相互に関連するレコードを照会するために使用されます。 |
SQL JOIN
SQL JOIN 句は、テーブル間の共通フィールドに基づいて、2つ以上のテーブルの行を結合するために使用されます。
最も一般的な JOIN の種類:SQL INNER JOIN(シンプルな JOIN)。 SQL INNER JOIN は、JOIN 条件を満たすすべての行を複数のテーブルから返します。
構文:
SELECT column1, column2, ... FROM table1 JOIN table2 ON condition;
パラメータの説明:
- column1, column2, ...:選択するフィールド名。複数のフィールドを指定できます。フィールド名を指定しない場合は、すべてのフィールドが選択されます。
- table1:結合する最初のテーブル。
- table2:結合する2番目のテーブル。
- condition:結合条件。結合方法を指定します。
デモデータベース
このチュートリアルでは、サンプル サンプルデータベースを使用します。
以下は "Websites" テーブルから選択したデータです:
+----+--------------+---------------------------+-------+---------+ | id | name | url | alexa | country | +----+--------------+---------------------------+-------+---------+ | 1 | Google | https://www.google.cm/ | 1 | USA | | 2 | 淘宝 | https://www.taobao.com/ | 13 | CN | | 3 | サンプル | http://www.example.com/ | 4689 | CN | | 4 | 微博 | http://weibo.com/ | 20 | CN | | 5 | Facebook | https://www.facebook.com/ | 3 | USA | | 7 | stackoverflow | http://stackoverflow.com/ | 0 | IND | +----+---------------+---------------------------+-------+---------+
以下は "access_log" ウェブサイトアクセス記録テーブルのデータです:
mysql> SELECT * FROM access_log; +-----+---------+-------+------------+ | aid | site_id | count | date | +-----+---------+-------+------------+ | 1 | 1 | 45 | 2016-05-10 | | 2 | 3 | 100 | 2016-05-13 | | 3 | 1 | 230 | 2016-05-14 | | 4 | 2 | 10 | 2016-05-14 | | 5 | 5 | 205 | 2016-05-14 | | 6 | 4 | 13 | 2016-05-15 | | 7 | 3 | 220 | 2016-05-15 | | 8 | 5 | 545 | 2016-05-16 | | 9 | 3 | 201 | 2016-05-17 | +-----+---------+-------+------------+ 9 rows in set (0.00 sec)
注意してください、"Websites" テーブルの "id" 列は "access_log" テーブルのフィールド "site_id"。上記の2つのテーブルは "site_id" 列によって関連付けられています。
次に、以下の SQL ステートメント(INNER JOIN を含む)を実行すると:
例
SELECT Websites.id, Websites.name, access_log.count, access_log.date
FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id;
FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id;
上記の SQL を実行すると、出力結果は次のとおりです:
さまざまな SQL JOIN
例の説明を続ける前に、使用できるさまざまな SQL JOIN の種類を一覧にします:
- INNER JOIN:テーブルに少なくとも1つの一致がある場合に行を返します
- LEFT JOIN:右テーブルに一致がなくても、左テーブルからすべての行を返します
- RIGHT JOIN:左テーブルに一致がなくても、右テーブルからすべての行を返します
- FULL JOIN:どちらかのテーブルに一致が存在する限り、行を返します
