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)で置き換えが可能