SQLのjoinの構文、内部結合、外部結合、主要DBMSでの構文についてまとめています。


SQLのjoinの構文
joinは複数テーブルの結合を行います。結合にはいくつか種類があります。以下は、左外部結合で、employees(社員)テーブルと、salaries(給与)テーブルを結合する例です。
- 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";
実行するとこうなります。employeesにしか存在したfirst_nameとlast_nameカラム、salariesテーブルにしか存在しないsalaryカラムの値が結合されて出力されています。
- +------------+-----------+--------+
- | 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 |
inner join(内部結合)とouter join(外部結合)
内部結合と外部結合の違いは、他方のテーブルに対応する値が存在しない場合でも抽出対象にするか、しないかです。内部結合は、対応する値が存在するレコードのみを対象とします。
- SELECT
- employees.first_name,
- employees.last_name,
- salaries.salary
- FROM
- employees
- inner join salaries on employees.emp_no = salaries.emp_no
- WHERE
- salaries.to_date = "9999-01-01"
実行するとこうなります。salariesテーブルに対応するemp_noのレコードがない場合は、抽出対象になりません。
- +------------+-----------+--------+
- | 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 |
【関連記事】
▶SQL inner joinの構文 innerの省略やUSINGを使った略記の方法
left joinとright join
外部結合には、left joinとright joinがあります。left joinは条件の左辺側(fromで記述したテーブル)を抽出し、右辺(joinで指定したテーブル)に対応する値が存在しなかった場合にはNULLを返します。
right joinは、右辺(joinで指定したテーブル)を抽出し、左辺(fromで指定したテーブル)に対応する値がない場合は、NULLを返します。
なお、全てのright joinはleft joinで書き換えが可能であるため、開発プロジェクトなどで可読性を上げるためにleft joinに統一することも検討すると良いでしょう。
cross join(交差結合)
cross joinは組み合わせ全てを総当りで出力する結合方法。直積とも言います。
- select first_name, salary from employees
- cross join salaries
- where employees.emp_no < 10005;
- +------------+--------+
- | first_name | salary |
- +------------+--------+
- | Chirstian | 60117 |
- | Parto | 60117 |
- | Bezalel | 60117 |
- | Georgi | 60117 |
- | Georgi | 60117 |
- | Chirstian | 62102 |
- | Parto | 62102 |
- | Bezalel | 62102 |
- | Georgi | 62102 |
- | Georgi | 62102 |
- | Chirstian | 66074 |
- | Parto | 66074 |
- | Bezalel | 66074 |
- | Georgi | 66074 |
- | Georgi | 66074 |
- | Chirstian | 66596 |
- | Parto | 66596 |
- | Bezalel | 66596 |
- | Georgi | 66596 |
- | Georgi | 66596 |
- | Chirstian | 66961 |
- :
- :
開発プロジェクト等ではなかなか使いみちがないのですが、データの「縦持ち」「横持ち」を入れ替える際に使われることがあります。
関連)[SQL]データの縦持ち、横持ちを入れ替える | Developers.IO
DBMSごとのjoin構文
Oracleのjoin構文
Oracleのjoin構文は以下の通り。
- FROM <statement1> [alias]
- [CROSS,LEFT,RIGHT,FULL] JOIN <statement2> [alias]
- ON (Boolean-expression) [JOIN <statementN> [alias] ON (Boolean-expression)]*
INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN、CROSS JOINがサポートされてます。
SQL Serverのjoin構文
SQL Serverのjoin構文は以下の通り。
- SELECT pv.ProductID, v.BusinessEntityID, v.Name
- FROM Purchasing.ProductVendor AS pv
- INNER JOIN Purchasing.Vendor AS v
- ON (pv.BusinessEntityID = v.BusinessEntityID)
- WHERE StandardPrice > $10
- AND Name LIKE N'F%';
SQL Serverでは、join句を使わずinner joinと同じ結果を記述できます。以下は、WHERE句のみで同じ結合条件を指定した例です。
- SELECT pv.ProductID, v.BusinessEntityID, v.Name
- FROM Purchasing.ProductVendor AS pv, Purchasing.Vendor AS v
- WHERE pv.BusinessEntityID=v.BusinessEntityID
- AND StandardPrice > $10
- AND Name LIKE N'F%';
内部結合、左外部結合、右外部結合、完全外部結合、クロス結合が記述可能です。
参考)結合 (SQL Server) – SQL Server | Microsoft Docs
MySQLのjoin構文
MySQLのjoin構文は以下の通り。複数テーブルの結合をカッコでまとめて記述できます。
- SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
- ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)
上記SQLは、cross joinを使った以下のSQLと同等になります。
- SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
- ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)
参考)MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.2.9.2 JOIN 構文
PostgreSQLのjoin構文
postgreSQLのjoin構文は以下の通り。
- => SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;
- num | name | num | value
- -----+------+-----+-------
- 1 | a | 1 | xxx
- 3 | c | 3 | yyy
- (2 rows)
INNER JOIN(内部結合)、LEFT OUTER JOIN(左外部結合)、RIGHT OUTER JOIN(右外部結合)、FULL OUTER JOIN(完全外部結合)が可能です。


まとめ

- joinは、テーブルの結合をおこなうSQL
- 内部結合、外部結合(左外部結合、右外部結合)、完全結合、クロス結合がある
- 右外部結合(right join)は、左外部結合(left join)で置き換えが可能