Der WHERE-Operator
Die Situation, in der wir Daten nach einer bestimmten Bedingung filtern wollen, kommt sehr häufig vor. Dafür gibt es im SELECT-Statement den Operator WHERE, gefolgt von den Bedingungen, die die Zeilen einschränken. Erfüllt ein Datensatz die Bedingung, landet er im Ergebnis – sonst wird er verworfen.
Allgemeine Struktur einer Query mit WHERE
MySQL 8.1SELECT [DISTINCT] tabellen_felder FROM tabellen_name WHERE bedingung_zur_zeilen_einschraenkung [logischer_operator weitere_bedingung_zur_zeilen_einschraenkung];
So kann zum Beispiel eine Query mit WHERE aussehen:
MySQL 8.1SELECT * FROM Student WHERE first_name = "Grigorij" AND YEAR(birthday) > 2000;
MySQL 8.1SELECT * FROM Student WHERE first_name = 'Grigorij' AND EXTRACT(YEAR FROM birthday) > 2000;
In diesem Beispiel verwenden wir gleich zwei Bedingungen:
- first_name = "Grigorij" — der Vorname des Studenten soll „Grigorij" sein
- YEAR(birthday) > 2000 — das Geburtsjahr liegt nach 2000
- first_name = 'Grigorij' — der Vorname des Studenten soll „Grigorij" sein
- EXTRACT(YEAR FROM birthday) > 2000 — das Geburtsjahr liegt nach 2000
Zwischen den beiden steht der logische Operator AND, der verlangt, dass beide Bedingungen gleichzeitig erfüllt sind. Im Ergebnis bekommen wir nur Studenten, auf die beide Kriterien zutreffen.
Vergleichsoperatoren
Um in SQL Werte zu vergleichen, gibt es spezielle Operatoren. Mit ihnen prüfst du, ob Werte gleich sind, ob einer größer ist als der andere, ob sie ungleich sind und so weiter. Das Ergebnis eines Vergleichs kann sein:
- true (entspricht 1)
- false (entspricht 0)
- NULL (wenn das Vergleichsergebnis undefiniert ist, z. B. beim Vergleich mit NULL)
Der Vergleich eines beliebigen Wertes mit NULL liefert NULL. Eine Ausnahme bildet der NULL-sichere Gleichheitsoperator.
Der Vergleich eines beliebigen Wertes mit NULL liefert NULL.
Probier diese Operatoren ruhig selbst in der Sandbox aus und schau, welche Ergebnisse rauskommen:
MySQL 8.1SELECT 2 = 1, 'a' = 'a', 1 <=> NULL, NULL <=> NULL, 2 <> 2, 3 < 4, 10 <= 10, 7 > 1, 8 >= 10;
MySQL 8.1SELECT 2 = 1 AS "2 = 1", 'a' = 'a' AS "'a' = 'a'", 2 <> 2 AS "2 <> 2", 3 < 4 AS "3 < 4", 10 <= 10 AS "10 <= 10", 7 > 1 AS "7 > 1", 8 >= 10 AS "8 >= 10";
Logische Operatoren
Logische Operatoren helfen dir, mehrere Bedingungen in einer SQL-Query zu kombinieren. Mit ihnen kannst du flexibel genau die Zeilen herauspicken, die du brauchst. Sehen wir uns das in der Praxis an:
-
AND — beide Bedingungen müssen erfüllt sein.
Stell dir vor, du suchst Flüge, die gleichzeitig zwei Anforderungen erfüllen: zum Beispiel ein bestimmtes Flugzeugmodell und ein bestimmter Abflugort. AND verknüpft diese Bedingungen.
MySQL 8.1SELECT * FROM Trip WHERE plane = 'Boeing' AND town_from = 'London';MySQL 8.1SELECT * FROM Trip WHERE plane = 'Boeing' AND town_from = 'London';Diese Query liefert nur Flüge, bei denen das Flugzeugmodell Boeing und der Abflugort London ist.
Wenn auch nur eine der Bedingungen nicht erfüllt ist (z. B. das Flugzeug ist kein Boeing oder der Abflug ist nicht aus London), landet der Flug nicht im Ergebnis.
-
OR — es reicht, wenn mindestens eine Bedingung erfüllt ist.
OR funktioniert wie ein „oder". Ist mindestens eine Bedingung wahr, landet die Zeile im Ergebnis. Praktisch, wenn du alle Flüge sehen willst, die mindestens eines deiner Kriterien erfüllen.
MySQL 8.1SELECT * FROM Trip WHERE town_to = 'Paris' OR plane = 'Airbus';MySQL 8.1SELECT * FROM Trip WHERE town_to = 'Paris' OR plane = 'Airbus';Das Ergebnis enthält alle Flüge nach Paris sowie alle Flüge mit einem Airbus (selbst wenn sie nicht nach Paris fliegen).
Ist ein Flug sowohl mit Airbus als auch nach Paris, landet er ebenfalls im Ergebnis.
-
NOT — kehrt die Bedingung um.
NOT invertiert die Bedingung: War sie wahr, wird sie falsch – und umgekehrt. Praktisch, wenn du bestimmte Werte ausschließen willst.
MySQL 8.1SELECT * FROM Trip WHERE NOT town_to = 'Moscow';MySQL 8.1SELECT * FROM Trip WHERE NOT town_to = 'Moscow';Diese Query liefert alle Flüge, deren Zielort nicht Moscow ist.
Ist der Zielort also Moscow, landet der Flug nicht im Ergebnis. Alles andere wird zurückgegeben.
-
XOR — wählt Zeilen aus, bei denen genau eine von zwei Bedingungen erfüllt ist, aber nicht beide gleichzeitig.
Angenommen, du willst Flüge finden, die entweder aus Moscow starten oder in Paris landen, aber nicht beides zusammen. Schauen wir uns alle Fälle an:
MySQL 8.1SELECT * FROM trip WHERE town_from = 'Moscow' XOR town_to = 'Paris';MySQL 8.1SELECT * FROM trip WHERE (town_from = 'Moscow' AND town_to != 'Paris') OR (town_from != 'Moscow' AND town_to = 'Paris');Hinweis: Den Operator XOR gibt es nicht in allen Datenbanken. Falls er fehlt, kann man ihn mit einer Kombination aus AND und OR nachbauen.
PostgreSQL hat keinen XOR-Operator, deshalb wird hier eine Kombination aus AND und OR verwendet, um dasselbe Ergebnis zu erzielen.
Priorität logischer Operatoren
Wenn du eine Query mit mehreren Bedingungen schreibst, muss SQL entscheiden, in welcher Reihenfolge es sie prüft. Das ist wie in der Mathematik: erst Punkt vor Strich. Für die logischen Operatoren in SQL gibt es ebenfalls eine feste Reihenfolge – die sogenannte Priorität.
- Zuerst — NOT
- Dann — AND
- Danach — XOR
- Zum Schluss — OR
Warum ist das wichtig?
Es mag so wirken, als würden die Bedingungen einfach von links nach rechts geprüft – ist aber nicht so! Wenn du die Reihenfolge ignorierst, bekommst du leicht unerwartete Ergebnisse.
Sieh dir dieses Beispiel an:
MySQL 8.1SELECT * FROM Trip WHERE town_to = 'Paris' OR plane = 'Boeing' AND NOT town_from = 'Moscow';
MySQL 8.1SELECT * FROM Trip WHERE town_to = 'Paris' OR plane = 'Boeing' AND NOT town_from = 'Moscow';
Was passiert hier:
-
Zuerst wird geprüft, ob der Flug nicht aus Moscow startet (NOT town_from = 'Moscow').
-
Dann wird geschaut, ob das Flugzeug ein Boeing ist, und dies wird per AND mit der ersten Bedingung kombiniert. Es werden also Flüge gesucht, die nicht aus Moscow starten und ein Boeing sind (plane = 'Boeing' AND NOT town_from = 'Moscow').
-
Danach werden zum Ergebnis alle Flüge hinzugefügt, die in Paris landen, auch wenn sie nicht mit einem Boeing fliegen oder aus Moscow starten (town_to = 'Paris' OR ...).
Am Ende bekommst du folgende Ergebnismenge:
- Alle Flüge, die nicht aus Moscow starten und ein Boeing sind
- Plus alle Flüge, die in Paris landen
Wenn du die Reihenfolge der Prüfungen ändern oder den Code verständlicher machen willst, nutze Klammern. Was in Klammern steht, wird zuerst ausgewertet. Setzt man zum Beispiel die Klammern entsprechend der Priorität der Operatoren von Hand, wird sofort klar, wie die Query abgearbeitet wird.
MySQL 8.1SELECT * FROM Trip WHERE ( town_to = 'Paris' OR ( plane = 'Boeing' AND (NOT town_from = 'Moscow') ) );
MySQL 8.1SELECT * FROM Trip WHERE ( town_to = 'Paris' OR ( plane = 'Boeing' AND (NOT town_from = 'Moscow') ) );
Jetzt bist du dran: Angenommen, du möchtest alle Flüge erhalten, die aus Paris starten oder mit einem Boeing unterwegs sind, dabei aber nicht nach Moscow fliegen. Das schaffst du, indem du die Klammern in der Ursprungs-Query richtig setzt. Wie würdest du es machen?