JOINは、データベースにアクセスしたことのある人にはなじみがなく、多くの人があらゆる種類のJOINを知っており、多くの人がこれを完全に理解していません。
Table_AとTable_Bの2つのテーブルがあるとします。これら2つの表のデータは次のとおりです。
TABLE_A
PK Value
---- ----------
1 FOX
2 COP
3 TAXI
6 WASHINGTON
7 DELL
5 ARIZONA
4 LINCOLN
10 LUCENT
TABLE_B
PK Value
---- ----------
1 TROT
2 CAR
3 CAB
6 MONUMENT
7 PC
8 MICROSOFT
9 APPLE
11 SCOTCH
結合構文:
join_table:
table_reference JOIN table_factor [join_condition] //内连接
| table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition //外连接
| table_reference LEFT SEMI JOIN table_reference join_condition //左半连接
| table_reference CROSS JOIN table_reference [join_condition] (as of Hive 0.10)
table_reference:
table_factor //表
| join_table //join语句
table_factor:
tbl_name [alias] //表名[别名]
| table_subquery alias //子查寻[别名]
| ( table_references ) //带空号的table_reference
join_condition:
ON expression //on开头的条件语句
1.内部結合:(内部接続)
これは、最も単純で理解しやすい接続であり、最も一般的な接続です。このクエリは、右側のテーブル(テーブルB)に一致するレコードがある左側のテーブル(テーブルA)のすべてのレコードを返します。この接続は次のように記述されます。
SELECT <select_list>
FROM Table_A A
INNER JOIN Table_B B
ON A.Key = B.Key
-- Inner JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
INNER JOIN Table_B B
ON A.PK = B.PK
A_PK A_Value B_Value B_PK
---- ---------- ---------- ----
1 FOX TROT 1
2 COP CAR 2
3 TAXI CAB 3
6 WASHINGTON MONUMENT 6
7 DELL PC 7
(5 row(s) affected)
2.左JOIN :(左JOIN)
このクエリは、これらのレコードが右側のテーブル(テーブルB)のレコードと一致するかどうかに関係なく、左側のテーブル(テーブルA)のすべてのレコードを返します。また、正しいテーブルから一致するレコードを返します。この接続は次のように記述されます。
SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
-- Left JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK
A_PK A_Value B_Value B_PK
---- ---------- ---------- ----
1 FOX TROT 1
2 COP CAR 2
3 TAXI CAB 3
4 LINCOLN NULL NULL
5 ARIZONA NULL NULL
6 WASHINGTON MONUMENT 6
7 DELL PC 7
10 LUCENT NULL NULL
(8 row(s) affected)
3. JOINを除く左:(JOINの結果を除く左)
このクエリは、右側のテーブル(テーブルB)のどのレコードとも一致しない左側のテーブル(テーブルA)のすべてのレコードを返します。この接続は次のように記述されます。
SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL
-- Left Excluding JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK
WHERE B.PK IS NULL
A_PK A_Value B_Value B_PK
---- ---------- ---------- ----
4 LINCOLN NULL NULL
5 ARIZONA NULL NULL
10 LUCENT NULL NULL
(3 row(s) affected)
4.右結合:(右結合)
このクエリは、左側のテーブル(表A)のレコードと一致するレコードがこれらのレコードにあるかどうかに関係なく、右側のテーブル(表B)のすべてのレコードを返します。また、左側のテーブルで一致するレコードも返します。この接続は次のように記述されます。
SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
-- Right JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK
A_PK A_Value B_Value B_PK
---- ---------- ---------- ----
1 FOX TROT 1
2 COP CAR 2
3 TAXI CAB 3
6 WASHINGTON MONUMENT 6
7 DELL PC 7
NULL NULL MICROSOFT 8
NULL NULL APPLE 9
NULL NULL SCOTCH 11
(8 row(s) affected)
5. JOINを除く右:(右結合は内部結合の結果を除外します)
このクエリは、左側のテーブル(テーブルA)のどのレコードとも一致しない右側のテーブル(テーブルB)のすべてのレコードを返します。この接続は次のように記述されます。
SELECT <select_list>
FROM Table_A A
RIGHT JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL
-- Right Excluding JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL
A_PK A_Value B_Value B_PK
---- ---------- ---------- ----
NULL NULL MICROSOFT 8
NULL NULL APPLE 9
NULL NULL SCOTCH 11
(3 row(s) affected)
6、アウタージョイン:(アウタージョイン)
この接続は、完全外部接続または完全接続と呼ばれることもあります。このクエリは、2つのテーブルのすべてのレコードを返し、右側のテーブル(テーブルB)のレコードと一致する左側のテーブル(テーブルA)のレコードを結合します。この接続は次のように記述されます。
SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
-- Outer JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK
A_PK A_Value B_Value B_PK
---- ---------- ---------- ----
1 FOX TROT 1
2 COP CAR 2
3 TAXI CAB 3
6 WASHINGTON MONUMENT 6
7 DELL PC 7
NULL NULL MICROSOFT 8
NULL NULL APPLE 9
NULL NULL SCOTCH 11
5 ARIZONA NULL NULL
4 LINCOLN NULL NULL
10 LUCENT NULL NULL
(11 row(s) affected)
7、JOINを除く外部:(外部結合は内部結合結果を除外します)
このクエリは、左側のテーブル(テーブルA)のすべてのレコードと、右側のテーブル(テーブルB)で一致しないすべてのレコードを返します。このタイプの接続はまだ使用する必要はありませんが、他のすべてのタイプの接続を頻繁に使用しています。この接続は次のように記述されます。
SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL OR B.Key IS NULL
-- Outer Excluding JOIN
SELECT A.PK AS A_PK, A.Value AS A_Value,
B.Value AS B_Value, B.PK AS B_PK
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL
OR B.PK IS NULL
A_PK A_Value B_Value B_PK
---- ---------- ---------- ----
NULL NULL MICROSOFT 8
NULL NULL APPLE 9
NULL NULL SCOTCH 11
5 ARIZONA NULL NULL
4 LINCOLN NULL NULL
10 LUCENT NULL NULL
(6 row(s) affected)
外部結合では、内部結合レコードが最初に返され、次に右結合レコードが返され、左結合レコードが最後に返されることに注意してください(少なくとも、私のMicrosoft SQL Serverはこれを行います。もちろん、これにはORDERBYステートメントは必要ありません)。詳細については、Wikipediaの記事にアクセスしてください(ただし、エントリはグラフィカルではありません)。また、必要に応じて印刷できるチートシートも作成しました。下の画像を右クリックして[対象をファイルに保存]を選択すると、フルサイズの画像がダウンロードされます。