SQLでは、最初のテーブルの後に別の結合を追加することで、3つ以上のテーブルを結合できます。
ある結合を別の結合条件として指定することにより、ネストされた結合を実行することもできます。
構文
3つのテーブルを結合する最も一般的な方法は、次のようになります。
SELECT *
FROM Table1
INNER JOIN Table2
ON Condition
INNER JOIN Table3
ON Condition;
これは内部結合を使用しますが、他の結合と同様に、目的の結合タイプを指定できます。必要に応じて、結合タイプを組み合わせることもできます(以下の例)。
ある結合を別の結合の結合条件として指定することにより、ネストされた結合を使用することもできます。このように:
SELECT *
FROM Table1
JOIN (Table2
JOIN Table3
ON Condition)
ON Condition;
サンプルデータ–3つのテーブル
次の3つのテーブルがあるとします。
Customers
テーブル:
+--------------+----------------+----------------+----------------+ | CustomerId | CustomerName | PostalCityId | PhoneNumber | |--------------+----------------+----------------+----------------| | 1 | Homer McKenzie | 19586 | (308) 555-0100 | | 2 | Marge Pratt | 33475 | (406) 555-0100 | | 3 | Vlad Bernanke | NULL | (480) 555-0100 | | 4 | Bart Pitt | 21692 | (316) 555-0100 | | 5 | Lisa McQueen | 12748 | (212) 555-0100 | | 6 | Steve Simpson | 17054 | (701) 555-0100 | | 7 | Vinn Allen | 12152 | (423) 555-0100 | | 8 | Veejay Smith | 3673 | (303) 555-0100 | | 9 | Kasey Chin | 23805 | (201) 555-0100 | | 10 | Borat Lee | 37403 | (701) 555-0100 | +--------------+----------------+----------------+----------------+ (10 rows affected)
Cities
テーブル:
+----------+----------------+-------------------+--------------+ | CityId | CityName | StateProvinceId | Population | |----------+----------------+-------------------+--------------| | 3673 | Bow Mar | 6 | 866 | | 12152 | Frankewing | 44 | NULL | | 12748 | Gasport | 33 | 1248 | | 21692 | Medicine Lodge | 17 | 2009 | | 26483 | Peeples Valley | 3 | 428 | | 33475 | Sylvanite | 27 | 103 | | 17054 | Jessie | 35 | 25 | | 19586 | Lisco | 28 | NULL | | 37403 | Wimbledon | 35 | 216 | +----------+----------------+-------------------+--------------+ (9 rows affected)
StateProvinces
テーブル:
+-------------------+---------------------+---------------------+-------------+--------------+ | StateProvinceId | StateProvinceCode | StateProvinceName | CountryId | Population | |-------------------+---------------------+---------------------+-------------+--------------| | 3 | AZ | Arizona | 230 | 6891688 | | 6 | CO | Colorado | 230 | 5698265 | | 17 | KS | Kansas | 230 | 2893957 | | 28 | NE | Nebraska | 230 | 1943256 | | 31 | NJ | New Jersey | 230 | 8899339 | | 33 | NY | New York | 230 | 20437172 | | 35 | ND | North Dakota | 230 | 723393 | | 44 | TN | Tennessee | 230 | 6495978 | +-------------------+---------------------+---------------------+-------------+--------------+ (8 rows affected)
例1-内部結合3テーブル
最も一般的な結合タイプは内部結合であるため、それから始めます。
上記の3つのテーブルを2つの内部結合で結合する例を次に示します。
SELECT
s.StateProvinceName,
ci.CityName,
cu.CustomerName
FROM StateProvinces s
INNER JOIN Cities AS ci
ON ci.StateProvinceID = s.StateProvinceID
INNER JOIN Customers cu
ON cu.PostalCityId = ci.CityId;
結果:
+---------------------+----------------+----------------+ | StateProvinceName | CityName | CustomerName | |---------------------+----------------+----------------| | Nebraska | Lisco | Homer McKenzie | | Kansas | Medicine Lodge | Bart Pitt | | New York | Gasport | Lisa McQueen | | North Dakota | Jessie | Steve Simpson | | Tennessee | Frankewing | Vinn Allen | | Colorado | Bow Mar | Veejay Smith | | North Dakota | Wimbledon | Borat Lee | +---------------------+----------------+----------------+ (7 rows affected)
例2–結合タイプの組み合わせ
3つ以上のテーブルを結合するときに、結合タイプを組み合わせることができます。
これは、内側の結合と左の結合を組み合わせる例です。
SELECT
s.StateProvinceName,
ci.CityName,
cu.CustomerName
FROM StateProvinces s
INNER JOIN Cities AS ci
ON ci.StateProvinceID = s.StateProvinceID
LEFT JOIN Customers cu
ON cu.PostalCityId = ci.CityId;
結果:
---------------------+----------------+----------------+ | StateProvinceName | CityName | CustomerName | |---------------------+----------------+----------------| | Colorado | Bow Mar | Veejay Smith | | Tennessee | Frankewing | Vinn Allen | | New York | Gasport | Lisa McQueen | | Kansas | Medicine Lodge | Bart Pitt | | Arizona | Peeples Valley | NULL | | North Dakota | Jessie | Steve Simpson | | Nebraska | Lisco | Homer McKenzie | | North Dakota | Wimbledon | Borat Lee | +---------------------+----------------+----------------+ (8 rows affected)
この場合、まだ顧客がいない都市(ピープルズバレー)があります。
この情報を確認できる理由は、左側のテーブルに一致する行がない場合でも、左側の結合が左側のテーブルにデータを含む行を返すためです。
2つの内部結合を組み合わせた前の例では、この行は返されませんでした。これは、内部結合が両方のテーブルから一致しない行を破棄するためです。結合条件に一致する行が両方のテーブルに少なくとも1つある場合にのみ、行を返します。
新しいサンプルデータ–3つの異なるテーブル
残りの例では、次の表を使用します。
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)
Owners
テーブル:
+-----------+-------------+------------+----------------+-------------------+ | OwnerId | FirstName | LastName | Phone | Email | |-----------+-------------+------------+----------------+-------------------| | 1 | Homer | Connery | (308) 555-0100 | [email protected] | | 2 | Bart | Pitt | (231) 465-3497 | [email protected] | | 3 | Nancy | Simpson | (489) 591-0408 | NULL | | 4 | Boris | Trump | (349) 611-8908 | NULL | | 5 | Woody | Eastwood | (308) 555-0112 | [email protected] | +-----------+-------------+------------+----------------+-------------------+
注:
-
PetTypeId
Pets
の列 テーブルはPetTypeId
の外部キーですPetTypes
の テーブル(そのテーブルの主キーです)。 -
OwnerId
Pets
の列 テーブルはOwnerId
の外部キーですOwners
の列 テーブル。
例3–3つのテーブルを左結合
2つの左結合を使用して3つのテーブルの結合を実行しましょう。
これらのテーブルに対して2つの左結合を実行する例を次に示します。
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Owners o LEFT JOIN Pets p
ON p.OwnerId = o.OwnerId
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+----------------+ | PetName | PetType | PetOwner | |-----------+-----------+----------------| | Tweet | Bird | Homer Connery | | Scratch | Cat | Bart Pitt | | Bark | Dog | Bart Pitt | | Fluffy | Cat | Nancy Simpson | | Fetch | Dog | Nancy Simpson | | Wag | Dog | Nancy Simpson | | Fluffy | Dog | Boris Trump | | Meow | Cat | Boris Trump | | NULL | NULL | Woody Eastwood | +-----------+-----------+----------------+ (9 rows affected)
ここには、ペットを飼っていないペットの飼い主がいます。 Pets.OwnerId
を見ると、それを確認できます。 列を表示し、WoodyEastwoodのOwnerId
に対応する値がないことを確認します。 Owners
テーブル。
例4–3つのテーブルを右結合
右結合は左結合の反対です。同じ3つのテーブルを使用した例を次に示します。
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Pets p RIGHT JOIN Owners o
ON p.OwnerId = o.OwnerId
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+---------------+ | PetName | PetType | PetOwner | |-----------+-----------+---------------| | Tweet | Bird | Homer Connery | | Fluffy | Cat | Nancy Simpson | | Scratch | Cat | Bart Pitt | | Meow | Cat | Boris Trump | | Fetch | Dog | Nancy Simpson | | Wag | Dog | Nancy Simpson | | Fluffy | Dog | Boris Trump | | Bark | Dog | Bart Pitt | | NULL | Rabbit | | +-----------+-----------+---------------+ (9 rows affected)>
今回は追加のペットタイプ(Rabbit
)、ただし追加の所有者ではありません。これは、左側のテーブルに一致する行がない場合でも、右側の結合が右側のテーブルにデータを持つ行を返すためです。
ちなみに、最後のPetOwner
の理由 NULL
ではありません (最後のようにPetName
is)は、文字列の連結の結果であるためです。 T-SQLのCONCAT()
を使用しました 所有者の名前と名前を連結する機能。
例5–3つのテーブルを完全に結合する
完全結合は、左右の結合を1つにするようなものです。いずれかのテーブルに一致するデータがある限り、すべての行が返されます。
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Owners o FULL JOIN Pets p
ON p.OwnerId = o.OwnerId
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
結果:
+-----------+-----------+----------------+ | PetName | PetType | PetOwner | |-----------+-----------+----------------| | Tweet | Bird | Homer Connery | | Scratch | Cat | Bart Pitt | | Bark | Dog | Bart Pitt | | Fluffy | Cat | Nancy Simpson | | Fetch | Dog | Nancy Simpson | | Wag | Dog | Nancy Simpson | | Fluffy | Dog | Boris Trump | | Meow | Cat | Boris Trump | | NULL | NULL | Woody Eastwood | | NULL | Rabbit | | +-----------+-----------+----------------+ (10 rows affected)
今回は、前の2つの例で得られた結果の組み合わせを取得します。
例6–ネストされた結合
前述のように、ネストされた結合を実行することもできます。
ネストされた結合の例を次に示します。
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Owners o
LEFT JOIN (Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId)
ON p.OwnerId = o.OwnerId;
結果:
+-----------+-----------+----------------+ | PetName | PetType | PetOwner | |-----------+-----------+----------------| | Tweet | Bird | Homer Connery | | Scratch | Cat | Bart Pitt | | Bark | Dog | Bart Pitt | | Fluffy | Cat | Nancy Simpson | | Fetch | Dog | Nancy Simpson | | Wag | Dog | Nancy Simpson | | Fluffy | Dog | Boris Trump | | Meow | Cat | Boris Trump | | NULL | NULL | Woody Eastwood | +-----------+-----------+----------------+ (9 rows affected)