- Kategorien:
WHERE¶
Die WHERE
-Klausel gibt eine Bedingung an, die als Filter fungiert. Sie können die WHERE
-Klausel für folgende Aufgaben verwenden:
Filtern des Ergebnisses der FROM-Klausel einer SELECT-Anweisung
Angeben, auf welchen Zeilen UPDATE, MERGE oder DELETE ausgeführt werden sollen
Syntax¶
...
WHERE <predicate>
[ ... ]
predicate
Ein boolescher Ausdruck. Der Ausdruck kann logische Operatoren enthalten, beispielsweise
AND
,OR
undNOT
.
Nutzungshinweise¶
Prädikate in der WHERE-Klausel verhalten sich so, als würden sie nach der FROM-Klausel ausgewertet werden (auch wenn das Optimierungsprogramm Prädikate neu anordnen kann, wenn das keine Auswirkungen auf die Ergebnisse hat). Wenn beispielsweise ein Prädikat in der WHERE-Klausel auf Spalten einer Tabelle verweist, die Teil einer äußeren Verknüpfung in der FROM-Klausel ist, operiert der Filter auf den von der Verknüpfung zurückgegebenen Zeilen (die mit NULL-Werten aufgefüllt sein können).
Gehen Sie bei der Erstellung von Ausdrücken, die NULL-Werte auswerten können, mit großer Sorgfalt vor.
In den meisten Kontexten gibt der boolesche Ausdruck
NULL = NULL
den Wert NULL zurück und nicht TRUE. Erwägen Sie die Verwendung von IS [ NOT ] NULL, um NULL-Werte zu vergleichen.Wenn in einer
WHERE
-Klausel ein Ausdruck NULL ergibt, wird die Zeile für diesen Ausdruck aus dem Resultset entfernt (d. h. sie wird herausgefiltert).
Die maximale Anzahl von Ausdrücken in einer Liste ist 16.384. Die Begrenzung gilt zum Beispiel für die Anzahl der Ausdrücke in der folgenden SELECT-Anweisung:
SELECT column_x FROM mytable WHERE column_y IN (<expr1>, <expr2>, <expr3> ...);
Um das Erreichen des Limits zu vermeiden, führen Sie eine Join-Verknüpfung mit einer Lookup-Tabelle aus, die die Werte des Ausdrucks enthält, anstatt die Werte mit einer IN-Klausel anzugeben. Wenn beispielsweise die Ausdruckswerte aus dem vorherigen Beispiel zu einer Lookup-Tabelle namens
mylookuptable
hinzugefügt werden, können Sie die folgende Abfrage erfolgreich ausführen, selbst wenn die Lookup-Tabelle mehr als 16.384 Zeilen aufweist:SELECT column_x FROM mytable t JOIN mylookuptable l ON t.column_y = l.values_for_comparison;
Verknüpfungen in der WHERE-Klausel¶
Obwohl die WHERE
-Klausel in erster Linie der Filterung dient, kann die WHERE
-Klausel auch verwendet werden, um viele Typen von JOIN-Verknüpfungen auszudrücken. Allgemeine Informationen zum JOIN-Konzept finden Sie unter Verwenden von Verknüpfungen (Joins).
Eine WHERE
-Klausel kann eine Verknüpfung spezifizieren, indem sie JOIN-Bedingungen enthält, d. h. boolesche Ausdrücke, die definieren, welche Zeilen von einer Seite des JOIN mit welchen Zeilen der anderen Seite des JOIN übereinstimmen.
Die beiden folgenden äquivalenten Abfragen zeigen, wie sich eine innere Verknüpfung in der WHERE
- oder FROM-Klausel ausdrücken lässt:
SELECT t1.c1, t2.c2 FROM t1, t2 WHERE t1.c1 = t2.c2; SELECT t1.c1, t2.c2 FROM t1 INNER JOIN t2 ON t1.c1 = t2.c2;
Äußere Verknüpfungen können in der WHERE
-Klausel mit der (+)
-Syntax und in der FROM-Klausel mit den Schlüsselwörtern OUTER JOIN
angegeben werden.
Wenn Sie eine äußere Verknüpfung mit (+)
angeben, wendet die WHERE-Klausel die (+)
-Syntax auf jede Verknüpfungsspalte der Tabelle an, die „innen“ ist (wie unten definiert).
Bemerkung
Das Ergebnis einer äußeren Verknüpfung enthält eine Kopie aller Zeilen einer Tabelle. Unter diesem Thema wird die Tabelle, deren Zeilen erhalten bleiben, als „äußere“ Tabelle und die andere Tabelle als „innere“ Tabelle bezeichnet.
In einem LEFT OUTER JOIN ist die linke Tabelle die äußere Tabelle und die rechte Tabelle die innere Tabelle.
In einem RIGHT OUTER JOIN ist die rechte Tabelle die äußere Tabelle und die linke Tabelle die innere Tabelle.
Die folgenden Abfragen enthalten äquivalente linke äußere Verknüpfungen, von denen eine den JOIN in der FROM
-Klausel und die andere den JOIN in der WHERE
-Klausel angibt:
SELECT t1.c1, t2.c2 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c2; SELECT t1.c1, t2.c2 FROM t1, t2 WHERE t1.c1 = t2.c2(+);
In der zweiten Abfrage steht (+)
auf der rechten Seite und identifiziert die innere Tabelle.
Nachfolgend finden Sie eine Beispielausgabe für beide Abfragen:
+-------+-------+ | T1.C1 | T2.C2 | |-------+-------| | 1 | 1 | | 2 | NULL | | 3 | 3 | | 4 | NULL | +-------+-------+
Wenn Sie eine Tabelle über mehrere Spalten verknüpfen, verwenden Sie die Notation (+)
für jede Spalte in der inneren Tabelle (t2
im folgenden Beispiel):
SELECT t1.c1, t2.c2 FROM t1, t2 WHERE t1.c1 = t2.c2 (+) AND t1.c3 = t2.c4 (+);Bemerkung
Es gibt viele Einschränkungen hinsichtlich der Frage, wo die
(+)
-Syntax verwendet werden darf. Äußere Verknüpfungen der FROM-Klausel sind auch aussagekräftiger. Snowflake empfiehlt, die Notation(+)
nur zum Portieren von Code zu verwenden, der diese Notation bereits nutzt. Bei neuem Code sollten Sie diese Notation vermeiden.Folgende Einschränkungen bestehen:
Die
(+)
-Notation kann nicht zum Erstellen vonFULL OUTER JOIN
verwendet werden. Es können lediglichLEFT OUTER JOIN
undRIGHT OUTER JOIN
erstellt werden. Folgendes ist beispielsweise nicht gültig. Die Anweisung führt zu folgender Fehlermeldung:SQL compilation error: Outer join predicates form a cycle between 'T1' and 'T2'.
-- NOT VALID select t1.c1 from t1, t2 where t1.c1 (+) = t2.c2 (+);Wenn eine Tabelle in einer Abfrage an mehreren Verknüpfung beteiligt ist, kann die
(+)
-Notation die Tabelle in nur einer dieser Verknüpfungen als innere Tabelle angeben. Das Folgende ist nicht gültig, weilt1
als innere Tabelle in zwei Verknüpfungen dient. Die Anweisung führt zu folgender Fehlermeldung:SQL compilation error: Table 'T1' is outer joined to multiple tables: 'T3' and 'T2'.
-- NOT VALID select t1.c1 from t1, t2, t3 where t1.c1 (+) = t2.c2 and t1.c1 (+) = t3.c3;Beachten Sie jedoch, dass Sie
(+)
verwenden können, um unterschiedliche Tabellen als innere Tabellen in verschiedenen Verknüpfungen derselben SQL-Anweisung zu identifizieren. Das folgende Beispiel verknüpft drei Tabellen:t1
,t2
undt3
, von denen zwei innere Tabellen sind (in verschiedenen Verknüpfungen). Diese Anweisung führt Folgendes aus:
Ein LEFT OUTER JOIN zwischen
t1
undt2
(wobeit2
die innere Tabelle ist).Ein LEFT OUTER JOIN zwischen
t2
undt3
(wobeit3
die innere Tabelle ist).select t1.c1 from t1, t2, t3 where t1.c1 = t2.c2 (+) and t2.c2 = t3.c3 (+);
Das (+)
kann unmittelbar neben dem Tabellen- und Spaltennamen stehen oder durch Leerzeichen getrennt sein. Die beiden folgenden Varianten sind gültig:
where t1.c1 = t2.c2(+) where t1.c1 = t2.c2 (+)
Eine Abfrage kann Verknüpfungen enthalten, die sowohl in der FROM ... ON ...
-Klausel als auch in der WHERE
-Klausel angegeben sind. Die Angabe von Verknüpfungen in verschiedenen Klauseln derselben Abfrage kann jedoch die Lesbarkeit dieser Abfrage erschweren.
Die Unterstützung von Verknüpfungen in der WHERE
-Klausel dient in erster Linie der Abwärtskompatibilität mit älteren Abfragen, die nicht die FROM ... ON ...
-Syntax verwenden. Snowflake empfiehlt beim Schreiben neuer Abfragen mit Verknüpfungen die Verwendung von FROM ... ON ...
. Weitere Details dazu finden Sie unter JOIN.
Beispiele¶
Einfache Beispiele für Filterung¶
Im Folgenden werden einige einfache Anwendungen der WHERE-Klausel veranschaulicht:
SELECT * FROM invoices WHERE invoice_date < '2018-01-01'; SELECT * FROM invoices WHERE invoice_date < '2018-01-01' AND paid = FALSE;
In diesem Beispiel wird eine Unterabfrage verwendet, um alle Rechnungen anzuzeigen, deren Rechnungsbeträge unter dem Durchschnitt liegen:
SELECT * FROM invoices WHERE amount < ( SELECT AVG(amount) FROM invoices ) ;
Ausführen von Verknüpfungen mit der WHERE
-Klausel¶
Um eine Verknüpfung in der WHERE
-Klausel anzugeben, listen Sie die zu verknüpfenden Tabellen in der FROM clause
auf, wobei Sie die Tabellen durch ein Komma trennen. Geben Sie die Verknüpfungsbedingung als Filter in der WHERE
-Klausel an, wie im folgenden Beispiel gezeigt:
SELECT t1.col1, t2.col1 FROM t1, t2 WHERE t2.col1 = t1.col1 ORDER BY 1, 2; +------+------+ | COL1 | COL1 | |------+------| | 2 | 2 | | 2 | 2 | | 3 | 3 | +------+------+
Bemerkung
Der Kommaoperator ist ältere Syntax für INNER JOIN
. Die folgende Anweisung zeigt die empfohlene Art und Weise, eine Verknüpfung mit neuerer Syntax auszuführen. Die folgende Abfrage entspricht der obigen Abfrage:
SELECT t1.col1, t2.col1 FROM t1 JOIN t2 ON t2.col1 = t1.col1 ORDER BY 1, 2; +------+------+ | COL1 | COL1 | |------+------| | 2 | 2 | | 2 | 2 | | 3 | 3 | +------+------+
Im nächsten Abschnitt werden Verknüpfungen über drei Tabellen gezeigt und der Unterschied im Verhalten bei Verwendung von keinem, einem oder zwei (+)
-Operatoren für äußere Verknüpfungen.
Bevor Sie die Abfragen ausführen, erstellen und laden Sie die Tabellen, die in den Verknüpfungen verwendet werden sollen:
create table departments ( department_ID INTEGER, department_name VARCHAR, location VARCHAR ); insert into departments (department_id, department_name, location) values (10, 'CUSTOMER SUPPORT', 'CHICAGO'), (40, 'RESEARCH', 'BOSTON'), (80, 'Department with no employees yet', 'CHICAGO'), (90, 'Department with no projects or employees yet', 'EREHWON') ; create table projects ( project_id integer, project_name varchar, department_id integer ); insert into projects (project_id, project_name, department_id) values (4000, 'Detect fake product reviews', 40), (4001, 'Detect false insurance claims', 10), (9000, 'Project with no employees yet', 80), (9099, 'Project with no department or employees yet', NULL) ; create table employees ( employee_ID INTEGER, employee_name VARCHAR, department_id INTEGER, project_id INTEGER ); insert into employees (employee_id, employee_name, department_id, project_id) values (1012, 'May Aidez', 10, NULL), (1040, 'Devi Nobel', 40, 4000), (1041, 'Alfred Mendeleev', 40, 4001) ;Führen Sie eine dreifache innere Verknüpfung aus. Dabei wird nicht
(+)
(oder das Schlüsselwort OUTER) verwendet, sodass es sich um eine innere Verknüpfung handelt. Die Ausgabe enthält nur Zeilen, für die es eine Abteilung, ein Projekt und einen Mitarbeiter gibt:SELECT d.department_name, p.project_name, e.employee_name FROM departments d, projects p, employees e WHERE p.department_id = d.department_id AND e.project_id = p.project_id ORDER BY d.department_id, p.project_id, e.employee_id; +------------------+-------------------------------+------------------+ | DEPARTMENT_NAME | PROJECT_NAME | EMPLOYEE_NAME | |------------------+-------------------------------+------------------| | CUSTOMER SUPPORT | Detect false insurance claims | Alfred Mendeleev | | RESEARCH | Detect fake product reviews | Devi Nobel | +------------------+-------------------------------+------------------+Führen Sie eine äußere Verknüpfung aus. Dies ähnelt der vorhergehenden Anweisung mit Ausnahme, dass hier
(+)
verwendet wird, um die zweite Verknüpfung zu einer rechten äußeren Verknüpfung zu machen. Das ergibt folgenden Effekt: Wenn eine Abteilung in der Ausgabe enthalten ist, dann sind alle Projekte dieser Abteilung enthalten, auch wenn diese Projekte keine Mitarbeiter haben:SELECT d.department_name, p.project_name, e.employee_name FROM departments d, projects p, employees e WHERE p.department_id = d.department_id AND e.project_id(+) = p.project_id ORDER BY d.department_id, p.project_id, e.employee_id; +----------------------------------+-------------------------------+------------------+ | DEPARTMENT_NAME | PROJECT_NAME | EMPLOYEE_NAME | |----------------------------------+-------------------------------+------------------| | CUSTOMER SUPPORT | Detect false insurance claims | Alfred Mendeleev | | RESEARCH | Detect fake product reviews | Devi Nobel | | Department with no employees yet | Project with no employees yet | NULL | +----------------------------------+-------------------------------+------------------+Führen Sie zwei äußere Verknüpfungen durch. Dies ähnelt der vorhergehenden Anweisung mit Ausnahme, dass hier
(+)
verwendet wird, um beide Verknüpfungen zu inneren Verknüpfungen zu machen. Der Effekt ist, dass alle Abteilungen einbezogen werden (auch wenn sie noch keine Projekte oder Mitarbeiter haben) und alle Projekte, die mit den Abteilungen verbunden sind (auch wenn sie noch keine Mitarbeiter haben). Beachten Sie, dass die Ausgabe Projekte ausschließt, die keine Abteilung haben.SELECT d.department_name, p.project_name, e.employee_name FROM departments d, projects p, employees e WHERE p.department_id(+) = d.department_id AND e.project_id(+) = p.project_id ORDER BY d.department_id, p.project_id, e.employee_id; +----------------------------------------------+-------------------------------+------------------+ | DEPARTMENT_NAME | PROJECT_NAME | EMPLOYEE_NAME | |----------------------------------------------+-------------------------------+------------------| | CUSTOMER SUPPORT | Detect false insurance claims | Alfred Mendeleev | | RESEARCH | Detect fake product reviews | Devi Nobel | | Department with no employees yet | Project with no employees yet | NULL | | Department with no projects or employees yet | NULL | NULL | +----------------------------------------------+-------------------------------+------------------+
(Denken Sie jedoch daran, dass Snowflake empfiehlt, das Schlüsselwort OUTER
in der FROM
-Klausel zu verwenden, anstatt den Operator (+)
in der WHERE
-Klausel).