SQL結合は、複数のテーブルを結合するクエリを実行する場所です。
このSQL結合チュートリアルでは、SQL結合の基本的な例と、さまざまな結合タイプの概要を示します。
SQL結合タイプ
ANSI SQL標準では、次の表に示すように、5種類の結合が指定されています。
結合タイプ | 説明 |
---|---|
INNER JOIN | 結合条件に一致する行が両方のテーブルに少なくとも1つある場合、行を返します。 |
LEFT OUTER JOIN また LEFT JOIN | 左側のテーブル(JOIN の左側)にデータがある行を返します キーワード)、右側のテーブルに一致する行がない場合でも。 |
RIGHT OUTER JOIN また RIGHT JOIN | 右側のテーブル(JOIN の右側)にデータがある行を返します キーワード)、左側のテーブルに一致する行がない場合でも。 |
FULL OUTER JOIN また FULL JOIN | テーブルの1つに一致するデータがある限り、すべての行を返します。 |
CROSS JOIN | 最初のテーブルの各行と2番目のテーブルの各行を組み合わせた行を返します。 |
次のように、さまざまな結合操作には他の用語もあります。
参加 | 説明 |
---|---|
自己参加 | テーブルがそれ自体に結合するとき。 |
自然結合 | 結合される2つのテーブルの共通列に基づく暗黙的な結合。 |
等結合 | 結合述語に等価比較のみを含む結合。 |
SQL結合構文
内部結合は、FROM
のいずれかで指定できます。 またはWHERE
条項。外部結合と相互結合は、FROM
で指定できます。 条項のみ。
FROM
でSQL結合を作成するには 句、次のようなことを行います:
SELECT *
FROM Table1 < JoinType > Table2 [ ON ( JoinCondition ) ]
JoinType
の場所 実行する結合の種類を指定し、JoinCondition
結合された行の各ペアに対して評価される述語を定義します。
WHERE
で結合を指定するには 句、次のようなことを行います:
SELECT *
FROM Table1, Table2 [ WHERE ( JoinCondition ) ]
繰り返しますが、JoinCondition
結合された行の各ペアに対して評価される述語を定義します。
また、すべて角かっこで囲まれています([]
)はオプションです。
このチュートリアルの例のサンプルテーブル
このチュートリアルのほとんどの例では、次の2つのテーブルに対して結合を実行します。
PetTypes
テーブル:
+-------------+-----------+ | PetTypeId | PetType | |-------------+-----------| | 1 | Bird | | 2 | Cat | | 3 | Dog | | 4 | Rabbit | +-------------+-----------+ (4 rows affected)
Pets
テーブル:
+---------+-------------+-----------+-----------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | |---------+-------------+-----------+-----------+------------| | 1 | 2 | 3 | Fluffy | 2020-11-20 | | 2 | 3 | 3 | Fetch | 2019-08-16 | | 3 | 2 | 2 | Scratch | 2018-10-01 | | 4 | 3 | 3 | Wag | 2020-03-15 | | 5 | 1 | 1 | Tweet | 2020-11-28 | | 6 | 3 | 4 | Fluffy | 2020-09-17 | | 7 | 3 | 2 | Bark | NULL | | 8 | 2 | 4 | Meow | NULL | +---------+-------------+-----------+-----------+------------+ (8 rows affected)
内部参加
SQL INNER JOIN
結合条件に一致する行が両方のテーブルに少なくとも1つある場合、行を返します。
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets
INNER JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;
結果:
-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
FROM
で内部結合を指定するには 句では、INNER JOIN
を使用します 。 ON
も使用します 結合された行の各ペアに対して評価される述部を定義するキーワード。
結合タイプに関係なく、列名をテーブル名で修飾します。これを行う理由は、テーブル間の列名に関するあいまいさを回避するためです。両方のテーブルに同じ名前の列が含まれている可能性があり(この例のように)、そのような場合、DBMSは参照している列を認識しません。列名の前にテーブル名を付けると、正しい列を参照していることが保証され、参照している列のあいまいさから生じる可能性のあるエラーを防ぐことができます。
この例では、両方のテーブルにPetTypeId
があります 桁。 Pets.PetTypeId
columnは、PetTypes.PetTypeId
への外部キーです。 そのテーブルの主キーである列。
この例では、すべてのペットが返されることがわかりますが、すべてのペットタイプが返されるわけではありません。 Pets
にはウサギがいません テーブル、つまりRabbits
ペットの種類は返却されません。
Rabbits
の理由 タイプが返されないのは、INNER JOIN
が原因です 結合条件に一致する行が両方のテーブルに少なくとも1つある場合にのみ、行を返します。この場合、Rabbits
1つのテーブル(PetTypes
)にのみ存在します 表)。
結合タイプはオプションであることに注意してください。したがって、ほとんどの(すべてではないにしても)DBMSでは、INNER
を省略できます。 キーワード。これを省略すると(つまり、JOIN
のみを指定する場合) )、内部結合であると見なされます。
したがって、上記の例を次のように書き直すことができます。
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets
JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId;
また、他のSQLステートメントと同様に、FROM
必要に応じて、句を1行にまとめることができます。
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;
エイリアス
SQL結合を実行するときは、テーブルエイリアスを使用するのが一般的な方法です。エイリアスは、コードをより簡潔で読みやすくするのに役立ちます。
したがって、前の例を次のように変更できます。
SELECT
p.PetName,
pt.PetType
FROM Pets p INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
結果:
-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
エクイジョイン
上記の結合は、 equi-joinとも呼ばれます。 。等結合は、結合述語に等式比較のみを含む結合です。
上記の結合を記述する別の方法は次のようになります:
SELECT
p.PetName,
pt.PetType
FROM
Pets p,
PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+
これは、WHERE
で内部結合を指定する例です。 句。テーブルのコンマ区切りリストを提供し、次にWHERE
を提供しただけです。 調子。 WHERE
を省略した場合 条件では、CROSS JOIN
になってしまいます。 。
多くの初心者は、上記の構文がINNER JOIN
よりもはるかに理解しやすいと感じています。 構文。必要に応じてこの構文を自由に使用できますが、ほとんどのSQLプロフェッショナルはINNER JOIN
を使用することを好むことに注意してください。 前の例の構文。
3つのテーブルを結合する内部結合など、その他の例については、SQL内部結合を参照してください。
正しい結合
RIGHT OUTER JOIN
とも呼ばれます 、RIGHT JOIN
右側のテーブル(JOIN
の右側)にデータがある行を返します キーワード)、左側のテーブルに一致する行がない場合でも。
SELECT
p.PetName,
pt.PetType
FROM Pets p
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
この場合、追加のPetType
を取得しました 値–Rabbit
–Pets
にペットがいない場合でも そのタイプのテーブル。これにより、NULL
になります PetName
の値 Rabbit
に対する列 。
3つのテーブルを結合する右結合など、その他の例については、SQL右結合を参照してください。
左の結合
LEFT OUTER JOIN
とも呼ばれます 、SQL LEFT JOIN
左側のテーブル(JOIN
の左側)にデータがある行を返します キーワード)、右側のテーブルに一致する行がない場合でも。
これは、RIGHT JOIN
の反対です。 。
前の例を左結合を使用するように変更すると、次の結果が得られます。
SELECT
p.PetName,
pt.PetType
FROM Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
この特定のケースでは、結果は内部結合の場合と同じです。
ただし、FROM
でテーブルの順序を入れ替えると 句を使用すると、前の例の右結合と同様の結果が得られます。
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
LEFT JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
したがって、左結合と右結合の結果の違いは、FROM
の列の順序にのみ依存することがわかります。 条項。
3つのテーブルを結合する左結合など、その他の例については、SQL左結合を参照してください。
完全参加
SQL FULL JOIN
(またはFULL OUTER JOIN
)いずれかのテーブルに一致するデータがある限り、すべての行を返します。
つまり、1つの結合で左と右の両方を結合するようなものです。
これが完全結合の例です。
SELECT
p.PetName,
pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
これにより、右結合で得られたのと同じ結果が返されますが、右テーブルに対応する値がない行が左テーブルにあった場合は、異なる結果が返されます。
テーブル名を入れ替えて、もう一度実行してみましょう。
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
同じ結果。
3つのテーブルを結合する完全結合など、その他の例については、SQL完全結合を参照してください。
クロスジョイン
SQL CROSS JOIN
最初のテーブルの各行と2番目のテーブルの各行を組み合わせた行を返します。
つまり、結合内のテーブルから行のデカルト積を返します。
SELECT
p.PetName,
pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Bird | | Fetch | Bird | | Scratch | Bird | | Wag | Bird | | Tweet | Bird | | Fluffy | Bird | | Bark | Bird | | Meow | Bird | | Fluffy | Cat | | Fetch | Cat | | Scratch | Cat | | Wag | Cat | | Tweet | Cat | | Fluffy | Cat | | Bark | Cat | | Meow | Cat | | Fluffy | Dog | | Fetch | Dog | | Scratch | Dog | | Wag | Dog | | Tweet | Dog | | Fluffy | Dog | | Bark | Dog | | Meow | Dog | | Fluffy | Rabbit | | Fetch | Rabbit | | Scratch | Rabbit | | Wag | Rabbit | | Tweet | Rabbit | | Fluffy | Rabbit | | Bark | Rabbit | | Meow | Rabbit | +-----------+-----------+ (32 rows affected)
ご想像のとおり、間違ったテーブルに対して実行すると、これは非常に危険です。
これを行うのと同じです:
SELECT
p.PetName,
pt.PetType
FROM Pets p, PetTypes pt;
WHERE
を追加できます クロス結合の句。これにより、内部結合になります。
このように:
SELECT
p.PetName,
pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
その他の例については、SQLクロス結合を参照してください。
自然な結合
SQL NATURAL JOIN
は、結合されたテーブルで同じ列名を持つ両方のテーブルのすべての列を比較することによって暗黙的に結合述部が発生する、一種の等結合です。
結果セットには、同じ名前の列のペアごとに1つの列のみが含まれます。同じ名前の列が見つからない場合、結果は相互結合になります。
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets NATURAL JOIN PetTypes;
結果:
petname | pettype ---------+--------- Fluffy | Cat Fetch | Dog Scratch | Cat Wag | Dog Tweet | Bird Fluffy | Dog Bark | Dog Meow | Cat (8 rows)
実際、ANSI規格で考慮されているように、自然結合は実際には結合タイプではありません。これは、結合を自然な結合にするためにオプションで挿入できるキーワードです。
したがって、上記の例をNATURAL INNER JOIN
に変更できます。 必要に応じて:
SELECT
Pets.PetName,
PetTypes.PetType
FROM Pets NATURAL INNER JOIN PetTypes;
前述のように、内部結合はデフォルトの結合タイプであるため、結合タイプを省略すると(たとえば、INNER
、LEFT
、RIGHT
など)、内部結合として扱われます。
これらの結果のフォーマットが以前の結果と異なって見える場合は、このクエリを実行するためにPostgreSQLにジャンプする必要があったためです。前の例をSQLServerで実行しましたが、SQLServerは自然結合をサポートしていません。
3つのテーブルを結合する自然結合など、その他の例については、SQL自然結合を参照してください。
セルフジョイン
SQL SELF JOIN
テーブルをそれ自体に結合しています。
自己結合の典型的な例は、Employeesテーブルにあります。このような表では、ある従業員が別の従業員に報告する場合があります。したがって、自己結合を使用して、従業員ID列とマネージャーID列のテーブルを結合できます。
次の表があるとします。
+--------------+-------------+------------+-------------+ | EmployeeId | FirstName | LastName | ReportsTo | |--------------+-------------+------------+-------------| | 1 | Homer | Connery | NULL | | 2 | Bart | Pitt | 1 | | 3 | Maggie | Griffin | 1 | | 4 | Peter | Farnsworth | 2 | | 5 | Marge | Morrison | NULL | | 6 | Lisa | Batch | 5 | | 7 | Dave | Zuckerberg | 6 | | 8 | Vlad | Cook | 7 | +--------------+-------------+------------+-------------+
このテーブルで自己参加して、すべての従業員とそのマネージャーを返すことができます。
SELECT
CONCAT(e1.FirstName, ' ', e1.LastName) AS Employee,
CONCAT(e2.FirstName, ' ', e2.LastName) AS Manager
FROM Employees e1
LEFT JOIN Employees e2
ON e1.ReportsTo = e2.EmployeeId;
結果:
+------------------+-----------------+ | Employee | Manager | |------------------+-----------------| | Homer Connery | | | Bart Pitt | Homer Connery | | Maggie Griffin | Homer Connery | | Peter Farnsworth | Bart Pitt | | Marge Morrison | | | Lisa Batch | Marge Morrison | | Dave Zuckerberg | Lisa Batch | | Vlad Cook | Dave Zuckerberg | +------------------+-----------------+
その他の例については、SQL自己結合を参照してください。