INNER JOIN
とLEFT SEMI JOIN
の違いは何ですか?
以下のシナリオでは、なぜ2つの異なる結果が得られますか?
INNER JOIN
結果セットははるかに大きくなります。誰か説明できますか? table_1
でのみ表示される名前をtable_2
で取得しようとしています。
SELECT name
FROM table_1 a
INNER JOIN table_2 b ON a.name=b.name
SELECT name
FROM table_1 a
LEFT SEMI JOIN table_2 b ON (a.name=b.name)
INNER JOIN
は、両方のテーブルから列を返します。 LEFT SEMI JOIN
は、左側のテーブルのレコードのみを返します。 (標準SQLの場合)と同等です:
SELECT name
FROM table_1 a
WHERE EXISTS(
SELECT * FROM table_2 b WHERE (a.name=b.name))
右側の列に複数一致する行がある場合、INNER JOIN
は一致する列ごとに1行を返しますが、LEFT SEMI JOIN
は左側のテーブルの行のみを返します。そのため、結果に異なる行数が表示されます。
Table_2にのみ表示されるtable_1内の名前を取得しようとしています。
その場合、LEFT SEMI JOIN
は使用する適切なクエリです。
2つの列(Id、Data)と次のデータのみを持つ2つのテーブルTableAとTableBがあるとします。
TableA:
+----+---------+
| Id | Data |
+----+---------+
| 1 | DataA11 |
| 1 | DataA12 |
| 1 | DataA13 |
| 2 | DataA21 |
| 3 | DataA31 |
+----+---------+
TableB:
+----+---------+
| Id | Data |
+----+---------+
| 1 | DataB11 |
| 2 | DataB21 |
| 2 | DataB22 |
| 2 | DataB23 |
| 4 | DataB41 |
+----+---------+
内部結合列Id
で、テーブルと一致するレコードのみの両方から列が返されます。
.----.---------.----.---------.
| Id | Data | Id | Data |
:----+---------+----+---------:
| 1 | DataA11 | 1 | DataB11 |
:----+---------+----+---------:
| 1 | DataA12 | 1 | DataB11 |
:----+---------+----+---------:
| 1 | DataA13 | 1 | DataB11 |
:----+---------+----+---------:
| 2 | DataA21 | 2 | DataB21 |
:----+---------+----+---------:
| 2 | DataA21 | 2 | DataB22 |
:----+---------+----+---------:
| 2 | DataA21 | 2 | DataB23 |
'----'---------'----'---------'
左結合(または左外部結合)の列Id
は、両方のテーブルの列と、左のテーブルのレコードと一致するレコード(右のテーブルのNULL値)を返します。
.----.---------.----.---------.
| Id | Data | Id | Data |
:----+---------+----+---------:
| 1 | DataA11 | 1 | DataB11 |
:----+---------+----+---------:
| 1 | DataA12 | 1 | DataB11 |
:----+---------+----+---------:
| 1 | DataA13 | 1 | DataB11 |
:----+---------+----+---------:
| 2 | DataA21 | 2 | DataB21 |
:----+---------+----+---------:
| 2 | DataA21 | 2 | DataB22 |
:----+---------+----+---------:
| 2 | DataA21 | 2 | DataB23 |
:----+---------+----+---------:
| 3 | DataA31 | | |
'----'---------'----'---------'
右結合(または右外部結合)列Id
で、両方のテーブルと、右テーブルのレコードと一致するレコード(左テーブルのNULL値)から列を返します。
┌────┬─────────┬────┬─────────┐
│ Id │ Data │ Id │ Data │
├────┼─────────┼────┼─────────┤
│ 1 │ DataA11 │ 1 │ DataB11 │
│ 1 │ DataA12 │ 1 │ DataB11 │
│ 1 │ DataA13 │ 1 │ DataB11 │
│ 2 │ DataA21 │ 2 │ DataB21 │
│ 2 │ DataA21 │ 2 │ DataB22 │
│ 2 │ DataA21 │ 2 │ DataB23 │
│ │ │ 4 │ DataB41 │
└────┴─────────┴────┴─────────┘
完全外部結合列Id
で、左テーブルのレコード(右テーブルのNULL値)と右テーブルのレコード(左テーブルのNULL値)を持つテーブルと一致するレコードの両方から列を返します):
╔════╦═════════╦════╦═════════╗
║ Id ║ Data ║ Id ║ Data ║
╠════╬═════════╬════╬═════════╣
║ - ║ ║ ║ ║
║ 1 ║ DataA11 ║ 1 ║ DataB11 ║
║ 1 ║ DataA12 ║ 1 ║ DataB11 ║
║ 1 ║ DataA13 ║ 1 ║ DataB11 ║
║ 2 ║ DataA21 ║ 2 ║ DataB21 ║
║ 2 ║ DataA21 ║ 2 ║ DataB22 ║
║ 2 ║ DataA21 ║ 2 ║ DataB23 ║
║ 3 ║ DataA31 ║ ║ ║
║ ║ ║ 4 ║ DataB41 ║
╚════╩═════════╩════╩═════════╝
Left Semi Join列Id
で、左側のテーブルからのみ列を返し、左側のテーブルからのみ一致するレコードを返します。
┌────┬─────────┐
│ Id │ Data │
├────┼─────────┤
│ 1 │ DataA11 │
│ 1 │ DataA12 │
│ 1 │ DataA13 │
│ 2 │ DataA21 │
└────┴─────────┘
Hiveで試し、以下の出力を得ました
表1
1、wqe、チェンナイ、インド
2、stu、salem、インド
3、ミア、バンガロール、インド
4、yepie、newyork、USA
テーブル2
1、wqe、チェンナイ、インド
2、stu、salem、インド
3、ミア、バンガロール、インド
5、chapie、Los angels、USA
内部結合
SELECT * FROM table1 INNER JOIN table2 ON(table1.id = table2.id);
1 wqeチェンナイインド1 wqeチェンナイインド
2ステューセーラムインド2ステューセーラムインド
3 MIAバンガロールインド3 MIAバンガロールインド
左結合
SELECT * FROM table1 LEFT JOIN table2 ON(table1.id = table2.id);
1 wqeチェンナイインド1 wqeチェンナイインド
2ステューセーラムインド2ステューセーラムインド
3 MIAバンガロールインド3 MIAバンガロールインド
4 yepie newyork USA NULL NULL NULL NULL
左半結合
SELECT * FROM table1 LEFT SEMI JOIN table2 ON(table1.id = table2.id);
1 WQEチェンナイインド
2 Stu Salemインド
3 MIAバンガロールインド
注:左のテーブルのレコードのみが表示されますが、左結合の場合は両方のテーブルレコードが表示されます