データベース 2018-07-18

MySQL JOIN vs UNION:違いと使い分けを実例で解説

MySQL の JOIN と UNION の違いを実例で解説。INNER JOIN・LEFT JOIN・UNION ALL などの使い分けとパフォーマンスへの影響を学べます。

Read in: en
MySQL JOIN vs UNION:違いと使い分けを実例で解説

概要

MySQLのJOINの種類とUNIONについてまとめる

INNER JOIN

指定カラムの値が一致するレコード同士を結合する。 指定したカラムの値が一致しない場合は結合しない。 (両方のテーブルに一致するデータだけ結合される。)

users +------+--------+------+ | id | sex | name | +------+--------+------+ | 0 | male | John | | 1 | female | Risa | | 2 | male | Taro | +------+--------+------+

accounts +------+---------+---------------------+ | id | user_id | created_at | +------+---------+---------------------+ | 0 | 0 | 2018-07-18 14:47:41 | | 1 | 1 | 2018-07-18 14:48:01 | | 3 | 3 | 2018-07-18 15:07:37 | +------+---------+---------------------+

SELECT * FROM users INNER JOIN accounts ON users.id = accounts.user_id +------+--------+------+------+---------+---------------------+ | id | sex | name | id | user_id | created_at | +------+--------+------+------+---------+---------------------+ | 0 | male | John | 0 | 0 | 2018-07-18 14:47:41 | | 1 | female | Risa | 1 | 1 | 2018-07-18 14:48:01 | +------+--------+------+------+---------+---------------------+

usersテーブルのidが2のレコードはaccoutsテーブルに一致するものが含まれないので結合されない。 accountsテーブルのuser_idが3のレコードはusersテーブルに一致するものが含まれないので結合されない。

LEFT OUTER JOIN

指定のカラムの値が一致するレコード同士を結合する。 左のテーブルに存在し、右のテーブルに存在しない値はNULLでパディングされる。 (左のテーブルに存在するレコードは全て結合される)

users +------+--------+------+ | id | sex | name | +------+--------+------+ | 0 | male | John | | 1 | female | Risa | | 2 | male | Taro | +------+--------+------+

accounts +------+---------+---------------------+ | id | user_id | created_at | +------+---------+---------------------+ | 0 | 0 | 2018-07-18 14:47:41 | | 1 | 1 | 2018-07-18 14:48:01 | | 3 | 3 | 2018-07-18 15:07:37 | +------+---------+---------------------+

SELECT * FROM users LEFT OUTER JOIN accounts ON users.id = accounts.id +------+--------+------+------+---------+---------------------+ | id | sex | name | id | user_id | created_at | +------+--------+------+------+---------+---------------------+ | 0 | male | John | 0 | 0 | 2018-07-18 14:47:41 | | 1 | female | Risa | 1 | 1 | 2018-07-18 14:48:01 | | 2 | male | Taro | NULL | NULL | NULL | +------+--------+------+------+---------+---------------------+

左のテーブルであるusersテーブルには、idが2のレコードがあるが、右のテーブルであるaccountテーブルには一致するものがないので、NULLでパディングして結合されている。

RIGHT OUTER JOIN

LEFT OUTER JOINの逆。 指定のカラムの値が一致するレコード同士を結合する。 右のテーブルに存在し、左のテーブルに存在しない値はNULLでパディングされる。 (右のテーブルに存在するレコードは全て結合される)

users +------+--------+------+ | id | sex | name | +------+--------+------+ | 0 | male | John | | 1 | female | Risa | | 2 | male | Taro | +------+--------+------+

accounts +------+---------+---------------------+ | id | user_id | created_at | +------+---------+---------------------+ | 0 | 0 | 2018-07-18 14:47:41 | | 1 | 1 | 2018-07-18 14:48:01 | | 3 | 3 | 2018-07-18 15:07:37 | +------+---------+---------------------+

SELECT * from users RIGHT OUTER JOIN accounts ON users.id = accounts.id +------+--------+------+------+---------+---------------------+ | id | sex | name | id | user_id | created_at | +------+--------+------+------+---------+---------------------+ | 0 | male | John | 0 | 0 | 2018-07-18 14:47:41 | | 1 | female | Risa | 1 | 1 | 2018-07-18 14:48:01 | | NULL | NULL | NULL | 3 | 3 | 2018-07-18 15:07:37 | +------+--------+------+------+---------+---------------------+

右のテーブルであるaccountsテーブルには、user_idが3のレコードがあるが、左のテーブルであるusersテーブルには一致するものがないので、NULLでパディングして結合されている。

CROSS JOIN

MySQLでは、CROSS JOINとINNER JOINは構文上同等。(参考:MySQL 8.2.1.11 ネストした結合の最適化

UNION

テーブルとテーブルの重複を省いた形で結合する。 条件として、列数が同じがテーブルでなければならない。

users +------+--------+------+ | id | sex | name | +------+--------+------+ | 0 | male | John | | 1 | female | Risa | | 2 | male | Taro | +------+--------+------+

accounts +------+---------+---------------------+ | id | user_id | created_at | +------+---------+---------------------+ | 0 | 0 | 2018-07-18 14:47:41 | | 1 | 1 | 2018-07-18 14:48:01 | | 3 | 3 | 2018-07-18 15:07:37 | +------+---------+---------------------+

SELECT * FROM users UNION SELECT * FROM accoounts +------+--------+---------------------+ | id | sex | name | +------+--------+---------------------+ | 0 | male | John | | 1 | female | Risa | | 2 | male | Taro | | 0 | 0 | 2018-07-18 14:47:41 | | 1 | 1 | 2018-07-18 14:48:01 | | 3 | 3 | 2018-07-18 15:07:37 | +------+--------+---------------------+

参考

Tags: MySQL join union
Share: 𝕏 Post Facebook Hatena
✏️ View source / Discuss on GitHub
☕ サポート

このブログを応援していただける方は、以下からサポートをお願いします。いただいたサポートはブログ運営・技術研鑽に活用します。


関連記事