- Kategorien:
JOIN¶
Bei einer JOIN
-Operation werden Zeilen aus zwei Tabellen — oder anderen tabellenartigen Quellen, z. B. Ansichten oder Tabellenfunktionen — kombiniert, um eine neue kombinierte Zeile zu erstellen, die in der Abfrage verwendet werden kann. Eine Erläuterung des JOIN-Konzepts finden Sie unter Verwenden von Verknüpfungen (Joins).
In diesem Thema wird beschrieben, wie man die JOIN
-Unterklausel in der FROM-Klausel verwendet. Mit der JOIN
-Unterklausel wird explizit oder implizit festgelegt, wie Zeilen in einer Tabelle mit den entsprechenden Zeilen einer anderen Tabelle in Beziehung gesetzt werden sollen. Sie können auch die ASOF JOIN-Unterklausel verwenden, mit der Zeitreihendaten über Zeitstempelspalten verknüpft werden, wenn ihre Werte eng aufeinander folgen, einander vorausgehen oder genau übereinstimmen.
Obwohl zum Verknüpfen von Tabellen die Verwendung von JOIN
mit der Unterklausel ON
der FROM
-Klausel empfohlen wird, können Tabellen alternativ auch mit der WHERE
-Klausel verknüpft werden. Weitere Informationen dazu finden Sie in der Dokumentation zur WHERE-Klausel.
Syntax¶
Verwenden Sie eine der folgenden Optionen:
SELECT ...
FROM <object_ref1> [
{
INNER
| { LEFT | RIGHT | FULL } [ OUTER ]
}
[ DIRECTED ]
]
JOIN <object_ref2>
[ ON <condition> ]
[ ... ]
SELECT *
FROM <object_ref1> [
{
INNER
| { LEFT | RIGHT | FULL } [ OUTER ]
}
[ DIRECTED ]
]
JOIN <object_ref2>
[ USING( <column_list> ) ]
[ ... ]
SELECT ...
FROM <object_ref1> [
{
NATURAL [
{
INNER
| { LEFT | RIGHT | FULL } [ OUTER ]
}
[ DIRECTED ]
]
| CROSS [ DIRECTED ]
}
]
JOIN <object_ref2>
[ ... ]
Parameter¶
object_ref1
undobject_ref2
Jede Objektreferenz ist eine Tabelle oder eine tabellenartige Datenquelle.
JOIN
Verwenden Sie das Schlüsselwort
JOIN
, um anzugeben, dass die Tabellen verknüpft werden sollen. Kombinieren SieJOIN
mit anderen verknüpfungsbezogenen Schlüsselwörtern (z. B.INNER
oderOUTER
), um den Typ der Verknüpfung (Join) festzulegen.Die Semantik von Verknüpfungen lautet wie folgt (der Kürze wegen werden unter diesem Thema
o1
undo2
fürobject_ref1
undobject_ref2
verwendet):Verknüpfungstyp
Semantik
o1 INNER JOIN o2
Bei jeder Zeile von
o1
wird für jede Zeile vono2
, die die UnterklauselON condition
erfüllt, eine Zeile erzeugt. (Sie können auch ein Komma verwenden, um eine innere Verknüpfung anzugeben. Ein Beispiel dazu finden Sie im Beispielabschnitt). Wenn SieINNER JOIN
ohne dieON
-Klausel verwenden (oder wenn Sie ein Komma ohne eineWHERE
-Klausel verwenden), ist das Ergebnis dasselbe wie bei Verwendung vonCROSS JOIN
: ein kartesisches Produkt (jede Zeile vono1
gepaart mit jeder Zeile vono2
).o1 LEFT OUTER JOIN o2
Das Ergebnis der inneren Verknüpfung wird für jede Zeile von
o1
, die keine Übereinstimmungen ino2
aufweist, um eine Zeile erweitert. Die Ergebnisspalten, die Bezug aufo2
nehmen, enthalten Null.o1 RIGHT OUTER JOIN o2
Das Ergebnis der inneren Verknüpfung wird für jede Zeile von
o2
, die keine Übereinstimmungen ino1
aufweist, um eine Zeile erweitert. Die Ergebnisspalten, die Bezug aufo1
nehmen, enthalten Null.o1 FULL OUTER JOIN o2
Gibt alle verknüpften Zeilen zurück, plus eine Zeile für jede Zeile ohne Entsprechung auf der linken Seite (rechts erweitert um Nullen), plus eine Zeile für jede Zeile ohne Entsprechung auf der rechten Seite (links erweitert um Nullen).
o1 CROSS JOIN o2
Für jede mögliche Kombination von Zeilen aus
o1
undo2
(d. h. Kartesisches Produkt) enthält die verknüpfte Tabelle eine Zeile, die aus allen Spalten ino1
gefolgt von allen Spalten ino2
besteht. EinCROSS JOIN
kann nicht mit einerON condition
-Klausel kombiniert werden. Sie können jedoch eineWHERE
-Klausel verwenden, um die Ergebnisse zu filtern.o1 NATURAL JOIN o2
Ein
NATURAL JOIN
ist identisch mit einem explizitenJOIN
für die gemeinsamen Spalten der beiden Tabellen, mit der Ausnahme, dass die gemeinsamen Spalten nur einmal in der Ausgabe enthalten sind. (Bei einer natürlichen Verknüpfung wird davon ausgegangen, dass Spalten mit dem gleichen Namen, die sich jedoch in verschiedenen Tabellen befinden, übereinstimmende Daten enthalten.) Beispiele dazu finden Sie im Beispielabschnitt. EinNATURAL JOIN
kann mit einemOUTER JOIN
kombiniert werden. EinNATURAL JOIN
kann nicht mit einerON condition
-Klausel kombiniert werden, da dieJOIN
-Bedingung bereits impliziert ist. Sie können jedoch eineWHERE
-Klausel verwenden, um die Ergebnisse zu filtern.Das
DIRECTED
-Schlüsselwort gibt eine gezielte Verknüpfung an, die die Join-Reihenfolge der Tabellen erzwingt. Die erste oder linke Tabelle wird vor der zweiten oder rechten Tabelle durchsucht. Beispiel:o1 INNER DIRECTED JOIN o2
scannt die Tabelleo1
vor der Tabelleo2
. Gezielte Verknüpfungen sind in den folgenden Situationen nützlich:Sie migrieren Workloads mit Richtlinien für die Verknüpfungsreihenfolge nach Snowflake.
Sie möchten die Leistung verbessern, indem Sie Verknüpfungstabellen in einer bestimmten Reihenfolge scannen.
Bemerkung
Die gezielte Verknüpfung ist ein Vorschau-Feature, das für alle Konten verfügbar ist.
Standard:
INNER JOIN
Wenn das Wort
JOIN
ohne Angabe vonINNER
oderOUTER
verwendet wird, dann wirdJOIN
als innere Verknüpfung interpretiert.Wenn das Schlüsselwort
DIRECTED
hinzugefügt wird, ist der Verknüpfungstyp – zum BeispielINNER
oderOUTER
– erforderlich.Siehe auch:
ON condition
Ein boolescher Ausdruck, der die Zeilen auf beiden Seiten des
JOIN
definiert, die als Übereinstimmung gelten. Beispiel:ON object_ref2.id_number = object_ref1.id_number
Bedingungen werden in der Dokumentation zur WHERE-Klausel näher erläutert.
Die
ON
-Klausel ist beiCROSS JOIN
nicht zulässig.Die Klausel
ON
ist beiNATURAL JOIN
unnötig und unzulässig; da die Verknüpfungsspalten impliziert sind.Bei anderen Verknüpfungen ist die
ON
-Klausel optional. Wenn Sie dieON
-Klausel jedoch weglassen, erhalten Sie ein kartesisches Produkt (jede Zeile vonobject_ref1
gepaart mit jeder Zeile vonobject_ref2
). Ein kartesisches Produkt kann eine sehr große Ausgabe erzeugen, die fast ausschließlich aus Zeilenpaaren besteht, die nicht wirklich miteinander zu tun haben. Dies erfordert viele Ressourcen und ist eine häufige Quelle für Benutzerfehler.USING( column_list )
Eine Liste der Spalten, die die beiden Tabellen, die verbunden werden sollen, gemeinsam haben. Diese Spalten werden als Verknüpfungsspalten verwendet. Die Spalten müssen in jeder der zu verbindenden Tabellen denselben Namen und dieselbe Bedeutung haben.
Angenommen, die SQL-Anweisung enthält Folgendes:
... o1 JOIN o2 USING (key_column)
In diesem einfachen Fall wäre dies äquivalent zu:
... o1 JOIN o2 ON o2.key_column = o1.key_column
In der Standard-JOIN-Syntax wird für die Projektionsliste (die Liste der Spalten und anderer Ausdrücke nach dem SELECT-Schlüsselwort)
*
verwendet. Dies führt dazu, dass die Abfrage genau einmal den Wert vonkey_column
zurückgibt. Die Spalten werden in der folgenden Reihenfolge zurückgegeben:Die Spalten in der
USING
-Klausel in der angegebenen Reihenfolge.Die linken Tabellenspalten, die nicht in der
USING
-Klausel angegeben sind.Die rechten Tabellenspalten, die nicht in der
USING
-Klausel angegeben sind.
Beispiele für standardmäßige und nicht standardmäßige Verwendung finden Sie im Beispielabschnitt.
Nutzungshinweise¶
Die folgenden Einschränkungen gelten für Tabellenfunktionen außer SQL-UDTFs:
Sie können die Klauseln
ON
,USING
oderNATURAL JOIN
nicht in einer lateralen Tabellenfunktion angeben, außer in einer SQL UDTF.Folgende Syntax ist beispielsweise nicht zulässig:
SELECT ... FROM my_table JOIN TABLE(FLATTEN(input=>[col_a])) ON ... ;
SELECT ... FROM my_table INNER JOIN TABLE(FLATTEN(input=>[col_a])) ON ... ;
SELECT ... FROM my_table JOIN TABLE(my_js_udtf(col_a)) ON ... ;
SELECT ... FROM my_table INNER JOIN TABLE(my_js_udtf(col_a)) ON ... ;
Sie können die Klauseln
ON
,USING
oderNATURAL JOIN
nicht in einem äußeren lateralen Join zu einer Tabellenfunktion angeben, außer in einer SQL UDTF.Folgende Syntax ist beispielsweise nicht zulässig:
SELECT ... FROM my_table LEFT JOIN TABLE(FLATTEN(input=>[a])) ON ... ;
SELECT ... FROM my_table FULL JOIN TABLE(FLATTEN(input=>[a])) ON ... ;
SELECT ... FROM my_table LEFT JOIN TABLE(my_js_udtf(a)) ON ... ;
SELECT ... FROM my_table FULL JOIN TABLE(my_js_udtf(a)) ON ... ;
Die Verwendung der Syntax führt zu folgendem Fehler:
000002 (0A000): Unsupported feature 'lateral table function called with OUTER JOIN syntax or a join predicate (ON clause)'
Diese Einschränkungen gelten nicht, wenn Sie anstelle des JOIN-Schlüsselworts ein Komma verwenden:
SELECT ... FROM my_table, TABLE(FLATTEN(input=>[col_a])) ON ... ;
Beispiele¶
In vielen der JOIN
-Beispiele werden zwei Tabellen genutzt: t1
und t2
. Erstellen Sie diese Tabellen und fügen Sie Daten ein:
CREATE TABLE t1 (col1 INTEGER);
INSERT INTO t1 (col1) VALUES
(2),
(3),
(4);
CREATE TABLE t2 (col1 INTEGER);
INSERT INTO t2 (col1) VALUES
(1),
(2),
(2),
(3);
Die folgenden Beispiele führen Abfragen mit Joins aus:
Führen Sie eine Abfrage mit einer linken äußeren Verknüpfung aus
Führen Sie eine Abfrage mit einer rechten äußeren Verknüpfung aus
Führen Sie eine Abfrage mit einer vollständigen äußeren Verknüpfung aus
Ausführen einer Abfrage, die Verknüpfungen in der FROM-Klausel kombiniert
Ausführen von Abfragen mit Joins, die die USING-Klausel verwenden
Führen Sie eine Abfrage mit einer inneren Verknüpfung aus¶
Im folgenden Beispiel wird eine Abfrage mit einer inneren Verknüpfung ausgeführt:
SELECT t1.col1, t2.col1
FROM t1 INNER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
+------+------+
Führen Sie dieselbe Abfrage mit einer nach innen gerichteten Verknüpfung (Inner-Directed Join) aus, um die Verknüpfungsreihenfolge zu erzwingen, sodass die linke Tabelle zuerst durchsucht wird:
Bemerkung
Die gezielte Verknüpfung ist ein Vorschau-Feature, das für alle Konten verfügbar ist.
SELECT t1.col1, t2.col1
FROM t1 INNER DIRECTED JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
+------+------+
Führen Sie eine Abfrage mit einer linken äußeren Verknüpfung aus¶
Im folgenden Beispiel wird eine Abfrage mit einer linken äußeren Verknüpfung (Left Outer Join) ausgeführt:
SELECT t1.col1, t2.col1
FROM t1 LEFT OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
In der Ausgabe gibt es einen NULL-Wert für die Zeile in Tabelle t1
, für die in Tabelle t2
keine übereinstimmende Zeile vorhanden ist:
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | NULL |
+------+------+
Führen Sie eine Abfrage mit einer rechten äußeren Verknüpfung aus¶
Im folgenden Beispiel wird eine Abfrage mit einer rechten äußeren Verknüpfung (Right Outer Join) ausgeführt:
SELECT t1.col1, t2.col1
FROM t1 RIGHT OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
In der Ausgabe gibt es einen NULL-Wert für die Zeile in Tabelle t1
, für die in Tabelle t2
keine übereinstimmende Zeile vorhanden ist.
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| NULL | 1 |
+------+------+
Führen Sie eine Abfrage mit einer vollständigen äußeren Verknüpfung aus¶
Im folgenden Beispiel wird eine Abfrage mit einer vollständigen äußeren Verknüpfung (Full Outer Join) ausgeführt:
SELECT t1.col1, t2.col1
FROM t1 FULL OUTER JOIN t2
ON t2.col1 = t1.col1
ORDER BY 1,2;
Jede Tabelle hat eine Zeile, für die in der anderen Tabelle keine übereinstimmende Zeile vorhanden ist, sodass die Ausgabe zwei Zeilen mit NULL-Werten enthält:
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
| 4 | NULL |
| NULL | 1 |
+------+------+
Ausführen einer Abfrage mit einer Kreuzverknüpfung¶
Im folgenden Beispiel wird eine Abfrage mit einer Kreuzverknüpfung (Cross Join) ausgeführt:
Bemerkung
Eine Kreuzverknüpfung hat keine ON-Klausel.
SELECT t1.col1, t2.col1
FROM t1 CROSS JOIN t2
ORDER BY 1, 2;
Die Ausgabe zeigt, dass die Abfrage ein kartesisches Produkt erzeugt:
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 1 |
| 2 | 2 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 2 |
| 3 | 3 |
| 4 | 1 |
| 4 | 2 |
| 4 | 2 |
| 4 | 3 |
+------+------+
Eine Kreuzverknüpfung kann durch eine WHERE
-Klausel gefiltert werden, wie im folgenden Beispiel gezeigt:
SELECT t1.col1, t2.col1
FROM t1 CROSS JOIN t2
WHERE t2.col1 = t1.col1
ORDER BY 1, 2;
+------+------+
| COL1 | COL1 |
|------+------|
| 2 | 2 |
| 2 | 2 |
| 3 | 3 |
+------+------+
Ausführen einer Abfrage mit einer natürlichen Verknüpfung¶
Das folgende Beispiel zeigt eine Abfrage mit einer natürlichen Verknüpfung (Natural Join). Erstellen Sie zunächst zwei Tabellen und fügen Sie Daten ein:
CREATE OR REPLACE TABLE d1 (
id NUMBER,
name VARCHAR);
INSERT INTO d1 (id, name) VALUES
(1,'a'),
(2,'b'),
(4,'c');
CREATE OR REPLACE TABLE d2 (
id NUMBER,
value VARCHAR);
INSERT INTO d2 (id, value) VALUES
(1,'xx'),
(2,'yy'),
(5,'zz');
Ausführen einer Abfrage mit einer natürlichen Verknüpfung:
SELECT *
FROM d1 NATURAL INNER JOIN d2
ORDER BY id;
Die Ausgabe zeigt, dass eine natürliche Verknüpfung dieselbe Ausgabe erzeugt wie die entsprechende innere Verknüpfung, außer dass keine zweite Kopie der Join-Spalte enthalten ist:
+----+------+-------+
| ID | NAME | VALUE |
|----+------+-------|
| 1 | a | xx |
| 2 | b | yy |
+----+------+-------+
Das folgende Beispiel zeigt, dass natürliche Verknüpfungen mit äußeren Verknüpfungen kombinierbar sind:
SELECT *
FROM d1 NATURAL FULL OUTER JOIN d2
ORDER BY id;
+----+------+-------+
| ID | NAME | VALUE |
|----+------+-------|
| 1 | a | xx |
| 2 | b | yy |
| 4 | c | NULL |
| 5 | NULL | zz |
+----+------+-------+
Ausführen einer Abfrage, die Verknüpfungen in der FROM-Klausel kombiniert¶
Sie können in der FROM
-Klausel kombinieren. Erstellen Sie eine dritte Tabelle:
CREATE TABLE t3 (col1 INTEGER);
INSERT INTO t3 (col1) VALUES
(2),
(6);
Führen Sie eine Abfrage aus, die zwei Joins in der FROM Klausel verkettet:
SELECT t1.*, t2.*, t3.*
FROM t1
LEFT OUTER JOIN t2 ON (t1.col1 = t2.col1)
RIGHT OUTER JOIN t3 ON (t3.col1 = t2.col1)
ORDER BY t1.col1;
+------+------+------+
| COL1 | COL1 | COL1 |
|------+------+------|
| 2 | 2 | 2 |
| 2 | 2 | 2 |
| NULL | NULL | 6 |
+------+------+------+
In einer solchen Abfrage werden die Ergebnisse basierend auf den Verknüpfungen von links nach rechts bestimmt, wobei der Optimierer die Verknüpfungen neu anordnen kann, wenn eine andere Verknüpfungsreihenfolge das gleiche Ergebnis liefert. Wenn die rechte äußere Verknüpfung vor der linken äußeren Verknüpfung erfolgen soll, schreiben Sie die Abfrage wie folgt:
SELECT t1.*, t2.*, t3.*
FROM t1
LEFT OUTER JOIN
(t2 RIGHT OUTER JOIN t3 ON (t3.col1 = t2.col1))
ON (t1.col1 = t2.col1)
ORDER BY t1.col1;
+------+------+------+
| COL1 | COL1 | COL1 |
|------+------+------|
| 2 | 2 | 2 |
| 2 | 2 | 2 |
| 3 | NULL | NULL |
| 4 | NULL | NULL |
+------+------+------+
Ausführen von Abfragen mit Joins, die die USING-Klausel verwenden¶
Die nächsten beiden Beispiele zeigen die standardmäßige (ISO 9075) und die nicht standardmäßige Verwendung der USING
-Klausel. Beide werden von Snowflake unterstützt.
Dieses erste Beispiel zeigt die übliche Verwendung. Konkret enthält die Projektionsliste genau *
:
WITH
l AS (
SELECT 'a' AS userid
),
r AS (
SELECT 'b' AS userid
)
SELECT *
FROM l LEFT JOIN r USING(userid);
Obwohl die Beispielabfrage zwei Tabellen verbindet, und jede Tabelle über eine Spalte verfügt, und die Abfrage nach allen Spalten fragt, enthält die Ausgabe nur eine und nicht zwei Spalten:
+--------+
| USERID |
|--------|
| a |
+--------+
Das folgende Beispiel zeigt eine nicht standardmäßige Verwendung. Die Projektionsliste enthält etwas anderes als *
:
WITH
l AS (
SELECT 'a' AS userid
),
r AS (
SELECT 'b' AS userid
)
SELECT l.userid as UI_L,
r.userid as UI_R
FROM l LEFT JOIN r USING(userid);
Die Ausgabe enthält zwei Spalten, wobei die zweite Spalte entweder einen Wert aus der zweiten Tabelle oder NULL enthält:
+------+------+
| UI_L | UI_R |
|------+------|
| a | NULL |
+------+------+