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 ... ]
Copy

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;
      
      Copy

      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;
      
      Copy

      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;
      
      Copy

      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;
      
      Copy
  • 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');
Copy

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

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;
Copy
+-------+
| 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 ...
Copy

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;
Copy
+-------+
| 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;
Copy
+-------+
| 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 ...
Copy

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;
Copy
+--------------------+-------+
| 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);
Copy

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;
Copy

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;
Copy
+----------------+
| V::VARCHAR     |
|----------------|
| Adams, Douglas |
| 42             |
+----------------+
OSZAR »