WHERE: wahre Zeilen von falschen trennen
Vergleiche, AND und OR, LIKE-Muster — und die seltsame Regel, dass NULL nicht gleich etwas ist, nicht einmal sich selbst.
Im letzten Unterricht hast du Zeilen mit WHERE gefiltert. Jetzt schauen wir genau, was eine Bedingung überhaupt sagen kann, denn beim Filtern entstehen die meisten falschen Antworten. Die Kantine führt eine zweite Tabelle, orders, mit einer Zeile pro Bestellung: was gekauft wurde, für wie viel und ob bezahlt ist. In einer Zeile steht paid = NULL: Die Kantine weiß es noch nicht.
orders
+----+--------+-------+----------+
| id | item | price | paid |
+----+--------+-------+----------+
| 1 | soup | 2.50 | yes |
| 2 | salad | 2.80 | no |
| 3 | juice | 1.90 | yes |
| 4 | juice | 1.90 | NULL |
| 5 | soup | 2.50 | yes |
+----+--------+-------+----------+Die Tabelle orders: eine Zeile pro Bestellung, und ein unbekannter Wert in paid.Ein Vergleich wie price < 2.00 oder paid = 'yes' beschreibt die Tabelle nicht — er ist eine Frage, die du jeder Zeile einzeln stellst. Jede Zeile antwortet ja, nein oder ich kann es nicht sagen. WHERE behält genau die ja-Zeilen. Darum kann dieselbe Abfrage morgen eine andere Zeilenzahl liefern: Die Frage ist stabil, die Daten sind es nicht.
Lies beide Abfragen über die Tabelle orders und sage die Zeilen voraus, bevor du auf die Antwort schaust. AND verengt: eine Bedingung betrifft die Bezahlung, die andere den Preis, und beide müssen gelten. OR erweitert: Eine Zeile überlebt, wenn mindestens eine Seite wahr ist — der Preis allein rettet also die billigen Zeilen.
WHERE paid = 'yes' AND price < 2.00
rows kept: juice (1.90, yes)
WHERE paid = 'yes' OR price < 2.00
rows kept: soup, juice, juice, soupZwei Bedingungen über dieselbe Tabelle: Zeilen von AND, dann von OR.AND bindet stärker als OR — genau wie Multiplikation vor Addition in der Arithmetik. Wenn du etwas anderes meinst, setze Klammern. WHERE a = 1 OR b = 2 AND c = 3 bedeutet a = 1 OR (b = 2 AND c = 3), und Menschen machen diesen Fehler ständig — Klammern kosten nichts.
Gleichheit verlangt, dass der ganze Wert passt. LIKE vergleicht stattdessen mit einem Muster: % steht für beliebigen Text beliebiger Länge, auch für nichts. Deshalb fängt dish LIKE 'veggie%' alles, was mit veggie beginnt, und '%soup%' alles, das soup irgendwo enthält.
menu
+----+---------------+
| id | dish |
+----+---------------+
| 1 | veggie soup |
| 2 | chicken soup |
| 3 | veggie salad |
+----+---------------+
WHERE dish LIKE 'veggie%' matches: veggie soup, veggie salad
WHERE dish LIKE '%soup%' matches: veggie soup, chicken soupDie Tabelle menu und zwei LIKE-Muster über die Spalte dish.Jetzt die seltsamste Regel in SQL. Die Zeile mit paid = NULL verschwindet aus jeder Vergleichsabfrage. Nicht nur aus paid = 'no' und nicht nur aus paid = 'yes' — aus beiden. Um zu verstehen warum, schau an, was NULL eigentlich ist.
WHERE paid = 'yes'
rows kept: soup (1), juice (3), soup (5)
row 4: paid is NULL, dropped
NULL = NULL is not true, it is unknownWarum paid = 'yes' die NULL-Zeile fallen lässt, und warum NULL = NULL nicht wahr ist.NULL ist kein Wert, sondern das Fehlen eines Werts: Die Kantine weiß noch nicht, ob diese Bestellung bezahlt wurde. Zu fragen, ob ein unbekanntes Ding gleich ja ist, ist wie zu fragen, ob meine Kopfschmerzen von morgen gleich ja sind — die ehrliche Antwort ist nicht nein, sondern unbekannt. SQL nennt das unknown, und WHERE behält nur wahres — darum fällt die Zeile weg.
Praxis
Die Kantine will eine Liste der Artikel, die bezahlt wurden und an einem Tag dreimal oder öfter verkauft wurden. Schreibe eine Abfrage über die Tabelle sales: Sie hat die Spalten item, count und paid, wobei paid der Text 'yes' oder 'no' ist.
Hinweise
- Zwei Bedingungen müssen gleichzeitig gelten, und in SQL ist das ein Wort.
- Vergleiche Text in einfachen Anführungszeichen, Zahlen ohne: paid = 'yes' AND count >= 3.
- Die Spalte, die misst, wie oft ein Artikel verkauft wurde, heißt count.
Fünf Zeilen von orders werden mit WHERE paid = 'yes' geprüft. Eine Zeile hat paid = NULL. Wie viele Zeilen kommen zurück, und was passiert mit der NULL-Zeile?
Hinweise
- Frag bei jeder der fünf Zeilen: Ist die Bedingung wahr, falsch oder unbekannt?
- Eine Zeile bleibt nur, wenn die WHERE-Bedingung genau wahr ist; unbekannt fliegt wie falsch raus.
Ordne jedes Muster dem zu, was es in der Spalte dish findet.
Hinweise
- Das Zeichen % steht für beliebigen Text beliebiger Länge: davor, dahinter oder beides.
- Achte darauf, wo das Muster verankert ist: 'A%' muss mit A beginnen, '%A' muss mit A enden.