SQLの外部結合についてまとめています。


SQLの外部結合は軸テーブルのデータを全件取得する結合の一種
SQLの外部結合は、テーブル結合の一種。軸となるテーブルのデータに対応するデータが存在しなくても、すべてのデータを取得します。
具体的な外部結合の記述の例は以下の通りです。LEFT JOINあるいは、OUTER JOIN、RIGHT JOINで記述を行います。なお、RIGHT JOINはLEFT JOINで置き換え可能なため、実質外部結合とはLEFT JOINまたはOUTER JOINで記述可能です。
- SELECT (テーブル名.)カラム名(, ....)
- FROM テーブル1
- LEFT (OUTER) JOIN テーブル2
- ON テーブル2.カラム名 = テーブル1.カラム名
- (LEFT JOIN テーブル3
- ON テーブル3.カラム名 = テーブル1(2).カラム名)
【関連記事】
▶SQLの内部結合と外部結合の違いを把握しよう!【サンプルコードで解説】
以下は、外部結合の実行例です。employees(社員)テーブルと、salaries(年収)テーブルを外部結合して、社員の姓名(first_name、last_name)と年収(salary)を抽出しています。WHERE句の条件は、最新の年収額を抽出するためのものです。
- SELECT
- employees.first_name,
- employees.last_name,
- salaries.salary
- FROM
- employees
- left join salaries on employees.emp_no = salaries.emp_no
- WHERE
- salaries.to_date = "9999-01-01";
- +------------+-----------+--------+
- | first_name | last_name | salary |
- +------------+-----------+--------+
- | Georgi | Facello | 88958 |
- | Bezalel | Simmel | 72527 |
- | Parto | Bamford | 43311 |
- | Chirstian | Koblick | 74057 |
- | Kyoichi | Maliniak | 94692 |
- | Anneke | Preusig | 59755 |
- | Tzvetan | Zielinski | 88070 |
- | Sumant | Peac | 94409 |
- | Duangkaew | Piveteau | 80324 |
- | Patricio | Bridgland | 54423 |
- :
- :
軸となるemployeesに対応したsalaryのデータがすべて存在する場合、外部結合の結果と内部結合の結果は同じになります。対応するsalaryの結果がない場合、salaryの項目はNULLになります。
【関連記事】
▶SQL Joinサンプル集 Joinで遅いSQLの原因を調べる方法
外部結合のクエリの処理に時間がかかる場合、いずれかの結合部分がボトルネックになっている場合があります。パフォーマンス低下の原因を探るには実行計画を確認しましょう。
以下は、explain(MySQL)で、クエリの実行結果を確認した例です。salariesテーブルにて、テーブルフルスキャン(type=ALL)が発生しています。
- mysql> explain SELECT employees.first_name, employees.last_name, salaries.salary FROM employees left join salaries on employees.emp_no = salaries.emp_no WHERE salaries.to_date = "9999-01-01";
- +----+-------------+-----------+------------+--------+---------------+---------+---------+---------------------------+---------+----------+-------------+
- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
- +----+-------------+-----------+------------+--------+---------------+---------+---------+---------------------------+---------+----------+-------------+
- | 1 | SIMPLE | salaries | NULL | ALL | PRIMARY | NULL | NULL | NULL | 2838426 | 10.00 | Using where |
- | 1 | SIMPLE | employees | NULL | eq_ref | PRIMARY | PRIMARY | 4 | employees.salaries.emp_no | 1 | 100.00 | NULL |
- +----+-------------+-----------+------------+--------+---------------+---------+---------+---------------------------+---------+----------+-------------+
- 2 rows in set, 1 warning (0.00 sec)
3テーブルの外部結合の例
SQLで2つ以上の外部結合を記述することが可能です。以下は、employees(社員)テーブルと、dept_emp(部署・社員紐付け)テーブル、departments(部署)テーブルの3つを外部結合しています。
- SELECT employees.emp_no,
- dept_name
- FROM employees
- LEFT JOIN dept_emp
- ON dept_emp.emp_no = employees.emp_no
- LEFT JOIN departments
- ON departments.dept_no = dept_emp.dept_no
- LIMIT 10;
実行結果はこうなります。
- +--------+--------------------+
- | emp_no | dept_name |
- +--------+--------------------+
- | 10001 | Development |
- | 10002 | Sales |
- | 10003 | Production |
- | 10004 | Production |
- | 10005 | Human Resources |
- | 10006 | Development |
- | 10007 | Research |
- | 10008 | Development |
- | 10009 | Quality Management |
- | 10010 | Production |
- +--------+--------------------+
- 10 rows in set (0.05 sec)
【関連記事】
▶SQL 外部結合サンプルコード 3テーブル結合とパフォーマンス比較
まとめ

- 外部結合は、結合の一種で、軸となるテーブルに対応するデータがなくても全件を取得する
- 外部結合は、outer joinまたはleft joinで記述可能
- 2テーブル以上の複数テーブルの外部結合が可能