INNERJOINとLEFTSEMIJOINの違い


82

違いは何である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)

2
内側の結合はあなたの目標を達成します。この質問を見るまで、セミジョインについて聞いたことがありませんでした。
Dan Bracuk 2014

left semi joinより多くの行を返すべきですinner join
ゴードンリノフ2014

1
inner join両方のテーブルの間に一致がある場合にのみデータを返します。left join一致するレコードが第二テーブルに見つかった場合にかかわらず、最初のテーブルからデータを返します。
j03z 2014

11
@GordonLinoffは必ずしもそうではなくLEFT SEMI JOIN、右側に複数の一致がある場合でも、aは左側から1行のみを返します。アンは、INNER JOIN右側の複数の一致がある場合、複数の行を返します。
Dスタンレー

1
正しくない@ j03z。左半結合の目的が1)左のテーブルの情報のみを返すこと(他の人が言っているように)と2)一致に関係なく左のテーブルから行を返すこと(私が言うように)である場合、それは元の左側のテーブルだけです。これを実現するために結合は必要ありません。左の半結合は、1)左のテーブルから列のみを返し、2)右のテーブルで一致する行のみを返し、3)左から1つの行を返すか、より多くの一致。
カールG

回答:


120

INNER JOIN、両方のテーブルの列からデータを返すことができ、どちらかの側のレコードの値を複製して、複数の一致がある場合があります。ALEFT SEMI JOINは左側のテーブルからのみ列を返すことができ、右側のテーブルに1つ以上の一致がある場合(一致の数に関係なく)、左側のテーブルから各レコードの1つを生成します。これは(標準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内の名前を取得しようとしています。

次に、aLEFT SEMI JOINは使用する適切なクエリです。


本当にそんなものはありLEFT SEMI JOINますか?だけじゃないのSEMI JOIN?意味RIGHT SEMI JOINがありませんね。
ErikE 2014

ではハイブ、はい。
Dスタンレー

1
私が探していたものだけが素晴らしい答えです。答えをより正確に表現します: "... INNER JOINは、右側のテーブルの一致するごとに1つの行を返しますが、LEFT SEMI JOIN ...
Barak1731475 2015

2
これの反対は、キーに従って左側のテーブルの右側のテーブルからデータをフィルターで除外するLEFT ANTIJOINです。このナゲットを探している人のためにここに置いておきたいと思いました!
shantanusinghal 2017年

63

2つの列(Id、Data)と次のデータしかないTableAとTableBの2つのテーブルがあるとします。

TableA:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataA11 |
|  1 | DataA12 |
|  1 | DataA13 |
|  2 | DataA21 |
|  3 | DataA31 |
+----+---------+

表B:

+----+---------+
| 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 ║
╚════╩═════════╩════╩═════════╝

列の左半結合Id、左のテーブルからのみ列を返し、左のテーブルからのみ一致するレコードを返します。

┌────┬─────────┐
│ Id │  Data   │
├────┼─────────┤
│  1 │ DataA11 │
│  1 │ DataA12 │
│  1 │ DataA13 │
│  2 │ DataA21 │
└────┴─────────┘

以前はこれを「LEFTINNERJoin」と呼んでいました。
Anshul Joshi 2017

INNERJOINの結果からのA. *のDISTINCTは、LEFT SEMIJOINと同等です。
Teja 2018

4
Aに2つの同一のレコードが含まれているとすると、Distinctは安全に聞こえません。
DennisJaheruddin19年

結果が同じになったとしても、DISTINCTを使用すると、EXISTSに比べて費用がかかる可能性があります
manotheshark

32

Hiveで試して、以下の出力を取得しました

表1

1、wqe、チェンナイ、インド

2、stu、salem、インド

3、ミア、バンガロール、インド

4、yepie、newyork、USA

table2

1、wqe、チェンナイ、インド

2、stu、salem、インド

3、ミア、バンガロール、インド

5、chapie、Los angels、USA

内部結合

SELECT * FROM table1 INNER JOIN table2 ON(table1.id = table2.id);

1wqeチェンナイインド1wqeチェンナイインド

2stuセーラムインド2stuセーラムインド

3ミアバンガロールインド3ミアバンガロールインド

左結合

SELECT * FROM table1 LEFT JOIN table2 ON(table1.id = table2.id);

1wqeチェンナイインド1wqeチェンナイインド

2stuセーラムインド2stuセーラムインド

3ミアバンガロールインド3ミアバンガロールインド

4 yepie newyork USA NULL NULL NULL NULL

左半結合

SELECT * FROM table1 LEFT SEMI JOIN table2 ON(table1.id = table2.id);

1wqeチェンナイインド

2 stuセーラムインド

3ミアバンガロールインド

注:左側のテーブルのレコードのみが表示されますが、左側の結合の場合は両方のテーブルレコードが表示されます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.