Kategorien:

Abfragesyntax

WHERE

Die WHERE-Klausel gibt eine Bedingung an, die einer Teilmenge von Zeilen entspricht. 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>
[ ... ]
Prädikat

Ein boolescher Ausdruck. Der Ausdruck kann logische Operatoren enthalten, beispielsweise AND, OR und NOT.

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.

    • 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).

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

Die folgende Abfrage erstellt eine innere Verknüpfung:

SELECT t1.c1, t2.c2
    FROM t1, t2
    WHERE t1.c1 = t2.c2
    ORDER BY 1,2;

In der WHERE-Klausel können Verknüpfungen entweder zusätzlich zu oder anstelle ihrer Angabe in der FROM-Klausel ausgedrückt werden. Dazu müssen in die WHERE-Klausel Verknüpfungsbedingungen aufgenommen werden.

Die beiden folgenden äquivalenten Abfragen zeigen, wie sich eine Verknüpfung in der FROM- und in der WHERE-Klausel ausdrücken lässt:

SELECT c1, c2
FROM t1 INNER JOIN t2
        ON c1 = c2
ORDER BY 1,2;

SELECT c1, c2
FROM t1, t2
WHERE c1 = c2
ORDER BY 1,2;

Äußere Verknüpfungen können in der WHERE-Klausel mit der (+)-Syntax angegeben werden. Um eine äußere Verknüpfung mit (+) anzugeben, werden die Spalten aus der NULL-erweiterten Tabelle der Verknüpfung in der WHERE-Klausel mit (+) versehen.

Die folgenden zwei äquivalenten Abfragen zeigen, wie sich eine äußere Verknüpfung in der FROM- oder WHERE-Klausel ausdrücken lässt:

SELECT c1, c2
FROM t1 LEFT OUTER JOIN t2
        ON c1 = c2;

SELECT c1, c2
FROM t1, t2
WHERE c1 = c2(+);

Bemerkung

Es gibt viele Beschränkungen hinsichtlich der Frage, wo die (+)-Anmerkung erscheinen kann; äußere Verknüpfungen der FROM-Klausel sind ausdrucksvoller. Snowflake empfiehlt, die Notation (+) nur zum Portieren von Code zu verwenden, der diese Notation bereits nutzt. Bei neuem Code sollten Sie diese Notation vermeiden.

Beschränkungen beinhalten:

  • Die (+)-Notation kann nicht zum Erstellen von FULL OUTER JOIN verwendet werden. Es können lediglich LEFT OUTER JOIN und RIGHT OUTER JOIN erstellt werden.

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 die Verwendung von FROM ... ON ... beim Schreiben neuer Abfragen mit Verknüpfungen. 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 ä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).