Unterschied zwischen INNER JOIN und LEFT SEMI JOIN


84

Was ist der Unterschied zwischen einem INNER JOINund LEFT SEMI JOIN?

Warum erhalte ich im folgenden Szenario zwei unterschiedliche Ergebnisse?

Die INNER JOINErgebnismenge ist viel größer. Kann jemand erklären? Ich versuche, die Namen zu bekommen, die table_1nur in erscheinen 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
Die innere Verbindung wird Ihr Ziel erreichen. Ich hatte noch nie von einem Semi-Join gehört, bis ich diese Frage sah.
Dan Bracuk

Das left semi joinsollte mehr Zeilen zurückgeben als das inner join.
Gordon Linoff

1
Das inner joingibt nur Daten zurück, wenn zwischen beiden Tabellen eine Übereinstimmung besteht. Der left joingibt Daten aus der ersten Tabelle zurück, unabhängig davon, ob in der zweiten Tabelle ein übereinstimmender Datensatz gefunden wurde.
j03z

11
@GordonLinoff nicht unbedingt, a LEFT SEMI JOINgibt nur eine Zeile von links zurück, auch wenn rechts mehrere Übereinstimmungen vorhanden sind. An INNER JOINgibt mehrere Zeilen zurück, wenn rechts mehrere Übereinstimmungen vorhanden sind.
D Stanley

1
@ j03z das kann nicht richtig sein. Wenn der Zweck des linken Hemi-Joins darin besteht, 1) nur die Informationen in der linken Tabelle zurückzugeben (wie andere gesagt haben) und 2) Zeilen aus der linken Tabelle zurückzugeben, unabhängig von der Übereinstimmung (wie ich denke, Sie sagen), dann ist das nur die ursprüngliche linke Tabelle - dazu ist kein Join erforderlich. Ich denke, andere müssen richtig sein, dass der linke Hemi-Join 1) nur Spalten aus der linken Tabelle zurückgibt, 2) nur Zeilen zurückgibt, die in der rechten Tabelle übereinstimmen, und 3) eine einzelne Zeile von links für eine oder zurückgibt mehr Übereinstimmungen.
Carl G

Antworten:


125

Sie INNER JOINkönnen Daten aus den Spalten beider Tabellen zurückgeben und Werte von Datensätzen auf beiden Seiten duplizieren, die mehr als eine Übereinstimmung aufweisen. A LEFT SEMI JOINkann nur Spalten aus der linken Tabelle zurückgeben und liefert einen von jedem Datensatz aus der linken Tabelle, in der eine oder mehrere Übereinstimmungen in der rechten Tabelle vorhanden sind (unabhängig von der Anzahl der Übereinstimmungen). Es ist äquivalent zu (in Standard-SQL):

SELECT name
FROM table_1 a
WHERE EXISTS(
    SELECT * FROM table_2 b WHERE (a.name=b.name))

Wenn die rechte Spalte mehrere übereinstimmende Zeilen enthält, INNER JOINgibt a für jede Übereinstimmung in der rechten Tabelle eine Zeile zurück, während a LEFT SEMI JOINnur die Zeilen aus der linken Tabelle zurückgibt, unabhängig von der Anzahl der übereinstimmenden Zeilen auf der rechten Seite. Aus diesem Grund sehen Sie in Ihrem Ergebnis eine andere Anzahl von Zeilen.

Ich versuche, die Namen in Tabelle_1 zu erhalten, die nur in Tabelle_2 erscheinen.

Dann LEFT SEMI JOINist a die geeignete Abfrage.


Gibt es wirklich so etwas wie LEFT SEMI JOIN? Ist das nicht nur ein SEMI JOIN? Es macht keinen Sinn RIGHT SEMI JOIN, oder?
ErikE

In Hive ja.
D Stanley

1
tolle Antwort genau das, wonach ich gesucht habe. Ich würde die Antwort genauer formulieren: "... ein INNER JOIN gibt eine Zeile für jede übereinstimmende Zeile der rechten Tabelle zurück , während ein LEFT SEMI JOIN ...
Barak1731475

2
Das Gegenteil davon ist ein LEFT ANTI JOIN, der die Daten aus der rechten Tabelle in der linken Tabelle nach einem Schlüssel herausfiltert. Ich dachte, ich würde dieses Nugget hier für jemanden lassen, der vielleicht sucht!
Shantanusinghal

64

Angenommen, es gibt 2 Tabellen TabelleA und TabelleB mit nur 2 Spalten (ID, Daten) und folgenden Daten:

Tabelle A:

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

Tabelle B:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataB11 |
|  2 | DataB21 |
|  2 | DataB22 |
|  2 | DataB23 |
|  4 | DataB41 |
+----+---------+

Inner Join on column Idgibt Spalten aus beiden Tabellen und nur die übereinstimmenden Datensätze zurück:

.----.---------.----.---------.
| 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 |
'----'---------'----'---------'

Left Join (oder Left Outer Join) in der Spalte Idgibt Spalten sowohl aus den Tabellen als auch übereinstimmende Datensätze mit Datensätzen aus der linken Tabelle zurück (Nullwerte aus der rechten Tabelle):

.----.---------.----.---------.
| 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 |    |         |
'----'---------'----'---------'

Right Join (oder Right Outer Join) in der Spalte Idgibt Spalten aus beiden Tabellen zurück und vergleicht Datensätze mit Datensätzen aus der rechten Tabelle (Nullwerte aus der linken Tabelle):

┌────┬─────────┬────┬─────────┐
│ 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 │
└────┴─────────┴────┴─────────┘

Full Outer Join on-Spalte Idgibt Spalten sowohl aus den Tabellen als auch übereinstimmende Datensätze mit Datensätzen aus der linken Tabelle (Nullwerte aus der rechten Tabelle) und Datensätzen aus der rechten Tabelle (Nullwerte aus der linken Tabelle) zurück:

╔════╦═════════╦════╦═════════╗
║ 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 on-Spalte Idgibt nur Spalten aus der linken Tabelle und übereinstimmende Datensätze nur aus der linken Tabelle zurück:

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

Ich habe das als "LEFT INNER Join" bezeichnet.
Anshul Joshi

Die Unterscheidung von A. * vom INNER JOIN-Ergebnis entspricht LEFT SEMI JOIN.
Teja

4
Distinct klingt nicht sicher, vorausgesetzt, A enthält zwei identische Datensätze.
Dennis Jaheruddin

Selbst wenn das Ergebnis das gleiche ist, könnte die Verwendung von DISTINCT einen teureren Plan haben als EXISTS
manotheshark

32

Versuchte in Hive und bekam die folgende Ausgabe

Tabelle 1

1, wqe, chennai, indien

2, stu, salem, indien

3, Mia, Bangalore, Indien

4, yepie, newyork, USA

Tabelle 2

1, wqe, chennai, indien

2, stu, salem, indien

3, Mia, Bangalore, Indien

5, Chapie, Los Angels, USA

Inner Join

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

1 wqe chennai india 1 wqe chennai india

2 stu salem indien 2 stu salem indien

3 mia bangalore indien 3 mia bangalore indien

Links beitreten

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

1 wqe chennai india 1 wqe chennai india

2 stu salem indien 2 stu salem indien

3 mia bangalore indien 3 mia bangalore indien

4 yepie newyork USA NULL NULL NULL NULL

Linke Semi Join

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

1 wqe chennai india

2 stu salem indien

3 mia bangalore indien

Hinweis: Es werden nur Datensätze in der linken Tabelle angezeigt, während für Left Join beide angezeigten Tabellendatensätze angezeigt werden

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.