Mengenoperatoren¶
Set-Operatoren fassen die Zwischenergebnisse mehrerer Abfrageblöcke zu einem einzigen Resultset zusammen.
Allgemeine Syntax¶
[ ( ] <query> [ ) ] { INTERSECT | { MINUS | EXCEPT } | UNION [ ALL ] } [ ( ] <query> [ ) ]
[ ORDER BY ... ]
[ LIMIT ... ]
Allgemeine Nutzungshinweise¶
Jede Abfrage kann selbst Abfrageoperatoren enthalten, damit sich beliebig viele Abfrageausdrücke mit Mengenoperatoren kombinieren lassen.
Die Klauseln ORDER BY und LIMIT / FETCH werden auf das Ergebnis des Mengenoperators angewendet.
Bei Verwendung dieser Operatoren:
Stellen Sie sicher, dass für jede Abfrage die gleiche Anzahl von Spalten ausgewählt ist.
Stellen Sie sicher, dass die Datentypen der einzelnen Spalten in allen Zeilen der verschiedenen Quellen konsistent sind. Eines der Beispiele im Abschnitt Verwenden Sie den UNION-Operator und wandeln Sie nicht übereinstimmende Datentypen um veranschaulicht das mögliche Problem und die Lösung, wenn die Datentypen nicht übereinstimmen.
Im Allgemeinen sollten die „Bedeutungen“ sowie die Datentypen der Spalten übereinstimmen. Folgendes führt nicht zu den gewünschten Ergebnissen:
SELECT LastName, FirstName FROM employees UNION ALL SELECT FirstName, LastName FROM contractors;
Das Fehlerrisiko erhöht sich, wenn mit dem Sternchen alle Spalten einer Tabelle ausgewählt werden. Beispiel:
SELECT * FROM table1 UNION ALL SELECT * FROM table2;
Wenn die Anzahl der Spalten in den Tabellen gleich ist, die Spalten jedoch nicht in derselben Reihenfolge angeordnet sind, werden die Abfrageergebnisse wahrscheinlich fehlerhaft ausfallen.
Die Namen der Ausgabespalten basieren auf den Namen der Spalten der ersten Abfrage. Betrachten wir beispielsweise die folgende Abfrage:
SELECT LastName, FirstName FROM employees UNION ALL SELECT FirstName, LastName FROM contractors;
Diese Abfrage verhält sich, als wäre die Abfrage wie folgt:
SELECT LastName, FirstName FROM employees UNION ALL SELECT FirstName AS LastName, LastName AS FirstName FROM contractors;
Die Rangfolge der Mengenoperatoren entspricht den ANSI- und ISO SQL-Standards:
Die Operatoren UNION [ALL] und MINUS (EXCEPT) haben die gleiche Priorität.
Der Operator INTERSECT hat Vorrang vor UNION [ALL] und MINUS (EXCEPT).
Operatoren gleicher Priorität werden von links nach rechts verarbeitet.
Sie können Klammern verwenden, um das Auswerten der Ausdrücke in einer anderen Reihenfolge zu erzwingen.
Nicht alle Datenbankanbieter folgen dem ANSI/ISO-Standard für die Rangfolge von Mengenoperatoren. Snowflake empfiehlt die Verwendung von Klammern zur Angabe der Auswertungsreihenfolge, insbesondere wenn Sie Code von einem anderen Anbieter in Snowflake portieren oder Code schreiben, den Sie möglicherweise auf anderen Datenbanken oder auf Snowflake ausführen.
Beispieltabellen für Beispiele¶
Für die Beispiel unter diesem Thema werden die folgenden Beispieltabellen verwendet. Beide Tabellen haben eine Spalte für Postleitzahlen. In einer Tabelle wird die Postleitzahl jedes Verkaufsbüros erfasst, in der anderen die Postleitzahl jedes Kunden.
CREATE OR REPLACE TABLE sales_office_zip_example(
office_name VARCHAR,
zip VARCHAR);
INSERT INTO sales_office_zip_example VALUES ('sales1', '94061');
INSERT INTO sales_office_zip_example VALUES ('sales2', '94070');
INSERT INTO sales_office_zip_example VALUES ('sales3', '98116');
INSERT INTO sales_office_zip_example VALUES ('sales4', '98005');
CREATE OR REPLACE TABLE customer_zip_example(
customer VARCHAR,
zip VARCHAR);
INSERT INTO customer_zip_example VALUES ('customer1', '94066');
INSERT INTO customer_zip_example VALUES ('customer2', '94061');
INSERT INTO customer_zip_example VALUES ('customer3', '98444');
INSERT INTO customer_zip_example VALUES ('customer4', '98005');
INTERSECT¶
Gibt Zeilen mit Duplikatlöschung aus dem Resultset einer Abfrage zurück, die auch im Resultset einer anderen Abfrage erscheinen.
Syntax¶
SELECT ...
INTERSECT
SELECT ...
Beispiele zum INTERSECT-Operator¶
Fragen Sie die Beispieltabellen <label-operators_set_sample_tables> ab, um die Postleitzahlen zu finden, die sowohl ein Verkaufsbüro als auch einen Kunden haben:
SELECT zip FROM sales_office_zip_example
INTERSECT
SELECT zip FROM customer_zip_example;
+-------+
| ZIP |
|-------|
| 94061 |
| 98005 |
+-------+
MINUS , EXCEPT¶
Gibt die von der ersten Abfrage zurückgegebenen Zeilen zurück, die nicht auch von der zweiten Abfrage zurückgegeben werden.
Die Schlüsselwörter MINUS und EXCEPT haben dieselbe Bedeutung und können austauschbar verwendet werden.
Syntax¶
SELECT ...
MINUS
SELECT ...
SELECT ...
EXCEPT
SELECT ...
Beispiele zum MINUS-Operator¶
Fragen Sie die Beispieltabellen <label-operators_set_sample_tables> ab, um die Postleitzahlen in der Tabelle sales_office_zip_example
zu finden, die nicht auch in der Tabelle customer_zip_example
enthalten sind:
SELECT zip FROM sales_office_zip_example
MINUS
SELECT zip FROM customer_zip_example;
+-------+
| ZIP |
|-------|
| 98116 |
| 94070 |
+-------+
Fragen Sie die Beispieltabellen <label-operators_set_sample_tables> ab, um die Postleitzahlen in der Tabelle customer_zip_example
zu finden, die nicht auch in der Tabelle sales_office_zip_example
enthalten sind:
SELECT zip FROM customer_zip_example
MINUS
SELECT zip FROM sales_office_zip_example;
+-------+
| ZIP |
|-------|
| 98444 |
| 94066 |
+-------+
UNION [ ALL ]¶
Kombiniert die Resultsets aus zwei Abfragen:
UNION kombiniert mit doppelter Löschung.
UNION ALL kombiniert ohne doppelte Löschung.
Der Standardwert ist UNION (d. h. Löschen von Duplikaten).
Syntax¶
SELECT ...
UNION [ ALL ]
SELECT ...
Beispiele zum UNION-Operator¶
In den folgenden Beispielen wird der UNION-Operator verwendet.
Verwenden Sie den UNION-Operator, um die Ergebnisse von zwei Abfragen zu kombinieren¶
Verwenden Sie den UNION-Operator, um die Resultsets von zwei Abfragen auf die Beispieltabellen zu kombinieren:
SELECT office_name office_or_customer, zip FROM sales_office_zip_example
UNION
SELECT customer, zip FROM customer_zip_example
ORDER BY zip;
+--------------------+-------+
| OFFICE_OR_CUSTOMER | ZIP |
|--------------------+-------|
| sales1 | 94061 |
| customer2 | 94061 |
| customer1 | 94066 |
| sales2 | 94070 |
| sales4 | 98005 |
| customer4 | 98005 |
| sales3 | 98116 |
| customer3 | 98444 |
+--------------------+-------+
Verwenden Sie den UNION-Operator und wandeln Sie nicht übereinstimmende Datentypen um¶
Dieses Beispiel veranschaulicht ein mögliches Problem bei der Verwendung des UNION-Operators, wenn die Datentypen nicht übereinstimmen, und bietet dann die Lösung.
Erstellen Sie zunächst die Tabellen, und fügen Sie einige Daten ein:
CREATE OR REPLACE TABLE union_test1 (v VARCHAR);
CREATE OR REPLACE TABLE union_test2 (i INTEGER);
INSERT INTO union_test1 (v) VALUES ('Adams, Douglas');
INSERT INTO union_test2 (i) VALUES (42);
Führen Sie eine UNION-Operation mit verschiedenen Datentypen aus (ein VARCHAR-Wert in union_test1
und ein INTEGER-Wert in union_test2
):
SELECT v FROM union_test1
UNION
SELECT i FROM union_test2;
Diese Abfrage gibt einen Fehler zurück:
100038 (22018): Numeric value 'Adams, Douglas' is not recognized
Verwenden Sie jetzt die explizite Umwandlung, um die Eingaben in einen kompatiblen Typ zu konvertieren:
SELECT v::VARCHAR FROM union_test1
UNION
SELECT i::VARCHAR FROM union_test2;
+----------------+
| V::VARCHAR |
|----------------|
| Adams, Douglas |
| 42 |
+----------------+