SQLの複数テーブル使用についてまとめてます。
サンプルには、MySQLのサンプルデータベースEmployeesを使用しています。
JOINでSQLの複数テーブル使用が可能
まず、単純に複数テーブルからselectすると、こうなります。
mysql> SELECT employees.emp_no, first_name, last_name, dept_name FROM employees ,dept_emp,departments limit 10; +--------+------------+-----------+--------------------+ | emp_no | first_name | last_name | dept_name | +--------+------------+-----------+--------------------+ | 10211 | Vishu | Strehl | Research | | 10211 | Vishu | Strehl | Sales | | 10210 | Yuping | Alpin | Customer Service | | 10210 | Yuping | Alpin | Development | | 10210 | Yuping | Alpin | Finance | | 10210 | Yuping | Alpin | Human Resources | | 10210 | Yuping | Alpin | Marketing | | 10210 | Yuping | Alpin | Production | | 10210 | Yuping | Alpin | Quality Management | | 10210 | Yuping | Alpin | Research | +--------+------------+-----------+--------------------+
employees、dept_emp、departmentsテーブルから総当りでデータを取って来たような形になりました。これは意図した動きではありませんね。
内部結合(inner join)
テーブル間の紐付け条件を指定すると、employees(社員)テーブルに対応したdept_name(部署名)を取得するようになりました。
これをinner joinと言います。条件に指定したカラムの値が一致するデータのみを結合します。
内部結合では、相手テーブルに対応するデータがない場合、データ抽出を行いません。
mysql> SELECT employees.emp_no, first_name, last_name, dept_name FROM employees ,dept_emp,departments where employees.emp_no = dept_emp.emp_no and departments.dept_no = dept_emp.dept_no limit 10; +--------+-------------+-------------+------------------+ | emp_no | first_name | last_name | dept_name | +--------+-------------+-------------+------------------+ | 10011 | Mary | Sluis | Customer Service | | 10038 | Huan | Lortz | Customer Service | | 10049 | Basil | Tramer | Customer Service | | 10060 | Breannda | Billingsley | Customer Service | | 10088 | Jungsoon | Syrzycki | Customer Service | | 10098 | Sreekrishna | Servieres | Customer Service | | 10112 | Yuichiro | Swick | Customer Service | | 10115 | Chikara | Rissland | Customer Service | | 10126 | Kayoko | Valtorta | Customer Service | | 10128 | Babette | Lamba | Customer Service |
外部結合(outer join)
場合によっては、相手テーブルに対応するデータがなくても、NULL表示で良いからデータ取得したいケースがあります。
その場合は、外部結合(outer join)を使いましょう。
left joinは、left outer joinの略です。
以下の場合は、employeesテーブルに対応するdept_empやdepartmentsのデータがなくても、データを取得します。
SELECT employees.emp_no, first_name, last_name, dept_name FROM employees left join dept_emp on employees.emp_no = dept_emp.emp_no left join departments on dept_emp.dept_no = departments.dept_no limit 10; +--------+------------+-----------+--------------------+ | emp_no | first_name | last_name | dept_name | +--------+------------+-----------+--------------------+ | 10001 | xGeorgi | Facello | Development | | 10002 | Bezalel | Simmel | Sales | | 10003 | Parto | Bamford | Production | | 10004 | Chirstian | Koblick | Production | | 10005 | Kyoichi | Maliniak | Human Resources | | 10006 | Anneke | Preusig | Development | | 10007 | Tzvetan | Zielinski | Research | | 10008 | Saniya | Kalloufi | Development | | 10009 | Sumant | Peac | Quality Management | | 10010 | Duangkaew | Piveteau | Production | +--------+------------+-----------+--------------------+
【関連記事】
▶MySQLのleft joinサンプルコード onとusingの結合条件指定の違いは?
なぜ外部結合でleft joinを使うのかは、ベン図をイメージすると理解しやすいと思います。以下の記事を参考にしてください。
【関連記事】
▶SQL Joinサンプル集 Joinで遅いSQLの原因を調べる方法
まとめ
- 複数テーブルを取り扱うには、joinを使う
- 内部結合(inner join)は、where節に結合条件を記述
- 外部結合(outer join)は、where節にleft joinで結合条件を記述