Die WHERE-Klausel
Bis jetzt waren die Auswertungen zwar lustig, aber nicht sonderlich praxisgerecht. In den wenigsten Fällen wollen Sie immer alle Datensätze ausgeben. Nein, Sie wollen filtern können.
Haben Sie bereits die Plakat-Werbung von Galaxus gesehen? Drei Beispiele sehen so aus:
(https://www.persoenlich.com/kategorie-werbung/uberraschende-einsichten-aufs-plakat-gebracht)
Wie zum Geier weiss Galaxus dies? Na, sie analysieren eben ihre Daten über ihre Kund*innen. Und genau die passiert mit dem Schlüsselwort WHERE.
Syntax von WHERE
[WHERE Bedingung]
Die WHERE-Klausel innerhalb einer SELECT-Anweisung sorgt dafür, dass nur ganz bestimmte Datensätze angezeigt werden.
Beispielweise wollen Sie wissen, wie viele resp. welche Kund*innen aus Deutschland stammen. Das geht wie folgt:
SELECT * FROM tblKunden WHERE tLandID = 276;
Quizfrage
Was passiert, wenn Sie folgendes eingeben?
SELECT * FROM tblKunden WHERE tLand = "Deutschland";
Filter für Zahlen
Das Filtern nach einem Bereich beim Attribut tLandID ist ähnlich wie in Python:
SELECT * FROM tblKunden WHERE tLandID >= 752 AND tLandID <= 800;
Speziell dafür gibt es aber in SQL eine angenehmere Schreibweise:
SELECT * FROM tblKunden WHERE tLandID BETWEEN 752 AND 800;
Aufgabe 1
Filtern Sie die Tabelle so, dass nur noch Kund*innen der Schweiz erscheinen. Wie viele Datensätze erhalten Sie?
Aufgabe 2
Schauen Sie sich mal generell (ohne Filterung) die Spalte mit den Ländern an. Welche praktischen Probleme erkennen Sie hier?
Finden Sie heraus, wie viele Kunden kein Land vermerkt haben (natürlich mit SQL)?
Achtung, was Sie in dieser Datenbank erleben, darf in der Praxis, also in echten, scharf verwendeten Datenbanken, nicht passieren:
- einige Kunden haben kein Land zugeordnet
- einige haben einen Leerstring im Attribut tLandID
- andere haben einen NULLSTRING
Das mit dem Leerstring ist beispielsweise eine Unschönheit von SQLite (Leerstring in einem Integer-Attribut? Hallo? Was soll das?). In anderen Datenbanken würde hier stattdessen eine 0 stehen.
Zudem darf es in einer echten Datenbank gar nicht passieren, dass man eine Land-ID eingeben kann, welche in der Tabelle "tblLaender" gar nicht vorkommt (referentielle Integrität). Man kann eine Tabelle resp. ein Attribut einer Tabelle auch so definieren, dass es nicht leer resp. nicht NULL sein darf. Solche Dinge sind bei einer Datenbank im Produktiveinsatz zwingend nötig.
Ich musste diese Übungsdatenbank, mit der Sie rumspielen, gewaltsam kaputtmachen, damit Sie auf ein paar interessante Probleme stossen können😅.
Vergleichsoperatoren für Zahlen
Für Zahlen existieren in etwa die gleichen Vergleichsoperatoren, wie in Python, hier nochmals in der Übersicht aufgelistet:
Wert1 = Wert2 Wert1 > Wert2 Wert1 < Wert2 Wert1 >= Wert2 Wert1 <= Wert2 Wert1 <> Wert2 oder Wert1 != Wert2 Wert1 BETWEEN Wert2 Wert1 NOT BETWEEN Wert2
Aufgabe 3
Nun wechseln wir noch kurz in die Tabelle "tblBestellungen".
Wie viele Bestellungen mit Frachtkosten von CHF 150.- und mehr finden Sie?
Filter für Texte
Der einfache Textfilter sieht wie folgt aus:
SELECT * FROM tblKunden WHERE tNachname = "Moreno";
Der LIKE-Operator
Sobald Sie beispielsweise alle Personen auflisten wollen, deren Nachname mit dem Buchstaben "M" beginnen, dürfen Sie nicht mehr das Gleichheitszeichen verwenden, sondern müssen auf den LIKE-Operator wechseln:
SELECT * FROM tblKunden WHERE tNachname LIKE "M%";
M% als Filterkriterium bedeutet, dass in diesem Beispiel das Attribut "tNachname" mit einem M beginnen soll, danach aber beliebige Zeichen kommen können.
Aufgabe 5
Filtern Sie die Tabelle tblKunden so, dass nur noch Personen erscheinen, deren Vorname nicht mit A beginnen. Wie viele Datensätze erhalten Sie?
Aufgabe 6
Filtern Sie die Tabelle tblKunden so, dass Sie nur noch Personen kriegen, die mit Nachnamen mit einem M beginnen und als zweitletztes Zeichen ein e haben. Wie viele Datensätze erhalten Sie?
Aufgabe 7
Filtern Sie die Tabelle tblKunden so, dass nur noch Personen erscheinen, deren Vorname mit A beginnen und mit a enden. Wie viele Datensätze erhalten Sie?
Aufgabe 8
Sie haben herausgefunden, dass in Ihrer Kundentabelle Personen mit dem Name "Meier" in unterschiedlicher Schreibweise gespeichert sind.
Filtern Sie die Tabelle tblKunden entsprechend, damit Sie diese Varianten von "Meier" erhalten. Wie viele Datensätze erhalten Sie?
Filter für Datumsangaben
Die Filter für Datumsangaben sind in SQLite zwar mächtig, aber trotzdem lästig, weil es keinen Datentyp "Datum" für Attribute gibt; man muss ein Attribut mit dem Datentyp "TEXT" versehen. Das ist nicht ganz so glücklich…so muss man in einer produktiven Datenbank noch Regeln festlegen, welche die Eingabe eines korrekten Datums überprüfen.
Trotzdem können wir ein paar Abfragen erstellen, starten wir:
Als erstes lohnt es sich, rasch zu schauen, wie das Datum im Attribut "tBestellDatum" in der Tabelle "tblBestellungen" überhaupt gespeichert wird. Offensichtlich nach dem folgenden Format:
YYYY-MM-DD
Also können wir folgenden SQL-Befehl absetzen:
SELECT * FROM tblBestellungen WHERE tBestellDatum BETWEEN DATE('1999-11-01') AND DATE('1999-11-30')
Das sollten 21 Datensätze ergeben.
Hier sehen Sie wiederum die Einfachheit von BETWEEN .. AND ..
Müssten Sie die Bedingung mit den klassischen mathematischen Operatoren schreiben, müssten Sie es wie folgt schreiben…
Aufgabe 9
…ach, lassen wir das😅, das ist gerade eine gute Übung für Sie!
Ersetzen Sie das BETWEEN .. AND .. um, sodass Sie mit den folgenden Vergleichsoperatoren arbeiten: > < =
Heute vor 23 Jahren...
Ein interessantes WHERE-Statement sehen Sie hier:
SELECT * FROM tblBestellungen WHERE tBestellDatum < DATE('now', '-23 years')
Der letzte Tag vom aktuellen Monat
Den letzten Tag des aktuellen Monats herauszufinden, ist immer ein wenig ein Gebastel, da nicht alle Monate gleich viele Tage haben.
Geben Sie mal den folgenden SQL-Befehl ein:
SELECT DATE('now', 'start of month','+1 month','-1 day')
Das Beispiel gehört zwar eher in das Kapitel mit den Berechnungen, aber passt hier trotzdem😂.
Fällt Ihnen auf, dass Sie gar keine Tabelle angegeben haben? Auch kein Attribut, nix. Mit diesem Befehl geht es nur darum, ein einziges berechnetes Feld anzuzeigen. That's it. Selbstverständlich können wir dann diese Berechnung auch als Kriterium für Auswertungen verwenden. Aber es ging zuerst mal um die Berechnung und darum, diese zu testen, ob sie wirklich macht, was wir wollen.
Aufgabe 10
Jetzt können Sie mit Hilfe von diesem Filterkriterium herausfinden, ob es am letzten Tag dieses Monats Bestellungen hat😎. Good luck!🍀
Aufgabe 11
Und weil es grad so viel Spass macht. Wie viele Bestellungen kriegen Sie vom letzten Tag des nächsten Monats (das sind Vorbestellungen, wo man das Bestelldatum in der Zukunft gesetzt hat, keine Panik. Ich habe hiermit grad festgelegt, dass dies Sinn macht😂😂)?
Kombination von Filtern
Filter auf Spalten können Sie selbstverständlich auch kombinieren:
SELECT * FROM tblKunden WHERE tFunktionID = 1 AND tNachname LIKE "M%";
Aufgabe 12
Wie viele Bestellungen aus dem Jahr 2024 finden Sie, welche Frachtkosten von CHF 150.- und mehr aufweisen?
Aufgabe 13
Wie viele Bestellungen vom Kunden mit der Kunden-ID 32 finden Sie, welche ganz hohe oder ganz tiefe Frachtkosten hat? Konkret interessieren uns die Frachtkosten von CHF 300.- und grösser und die Frachtkosten weniger als CHF 5.-).