Modul Datenbanken IN EF Gymnasium Lerbermatt
Docs » sql:bedingungen

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";

Lösung

Da kommt eine Fehlermeldung…wenn Ihnen nicht klar ist, wieso, dann rufen Sie mich.

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?

Lösung

Der SQL-Befehl lautet:

SELECT * FROM tblKunden WHERE tLandID = 756;

Und Sie sollten 2 Personen kriegen.

Ist Ihnen nicht klar, wie Sie auf die LandID von 756 kommen? Öffnen Sie doch mal die Tabelle "tblLaender" und suchen dort drin nach "Schweiz". Die ID dazu ist eben diese 756😎.

Aufgabe 2

Schauen Sie sich mal generell (ohne Filterung) die Spalte mit den Ländern an. Welche praktischen Probleme erkennen Sie hier?

Lösung

  • Das erste Problem ist kein eigentliches Problem: wir sehen kein Land, sondern nur eine Nummer. Das ist korrekt und will man bei einer RDB erreichen. Wir werden später bei der JOIN-Anweisung sehen, dass wir es mit der Vernküpfung von zwei Tabellen schaffen, das Land wie gewünscht anzuzeigen
  • Das zweite Problem ist wirklich ein Problem: es scheint Personen zu geben, die kein Land haben. Das ist in der Praxis gar nicht gut und muss unter allen Umständen vermieden werden (Stichwort "Datenintegrität").

Finden Sie heraus, wie viele Kunden kein Land vermerkt haben (natürlich mit SQL)?

Lösung

Die beiden möglichen SQL-Befehle lauten:

SELECT * FROM tblKunden WHERE tLandID = "";
SELECT * FROM tblKunden WHERE tLandID IS NULL;
  • Sie sollten 5 Personen kriegen, welche einen leeren String in tLandID haben
  • Sie sollten 2 Personen kriegen, welche einen NULLSTRING in tLandID haben

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?

Lösung

Sie sollten 117 Bestellungen erhalten.

SELECT * FROM tblBestellungen WHERE tFrachtkosten >= 150;

Filter für Texte

Der einfache Textfilter sieht wie folgt aus:

SELECT * FROM tblKunden WHERE tNachname = "Moreno";

Aufgabe 4

Wie viele Personen stammen aus London?

Lösung

SELECT * FROM tblKunden WHERE tOrt = "London";

Es sollten sechs Personen aus London kommen.

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?

Lösung

Der SQL-Befehl lautet:

SELECT * FROM tblKunden WHERE tVorname NOT LIKE "A%";

Und Sie sollten 80 Personen kriegen.

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?

Lösung

Vielleicht haben Sie zuerst folgende Variante versucht:

SELECT * FROM tblKunden WHERE tNachname LIKE "M%e%";

Das zeigt zwar Personen an, aber viel zu viele. Zwischen dem Buchstaben M und dem Buchstaben e dürfen nämlich beliebig viele andere Zeichen vorkommen. Auch nach dem Buchstaben e dürfen beliebig viele Zeichenn kommen.

Das ist die Idee vom %-Operator.

Es gibt hier einen besseren Operator, und zwar der Underscore: _

Damit sagen Sie, dass nicht beliebig viele Zeichen an beliebig viel Stellen vorkommen dürfen, sondern nur an einer einzigen Stelle.

Ändern Sie den obigen SQL-Befehl wie folgt:

SELECT * FROM tblKunden WHERE tNachname LIKE "M%e_";

Jetzt muss konkret der zweitletzte Buchstabe im Nachnamen ein e sein. Und das liefert 11 Datensätze.

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?

Lösung

Der SQL-Befehl lautet:

SELECT * FROM tblKunden WHERE tVorname LIKE "A%a";

Und Sie sollten 4 Personen kriegen.

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?

Lösung

Die erste Idee lautet hier meist sowas:

SELECT * FROM tblKunden WHERE tNachname LIKE "M%er";

Das liefert aber zu viele Datensätze. Schauen Sie mal, welche da nicht passen.

Das Problem liegt wieder darin, dass zwischen dem M und dem er beliebig viele Zeichen vorkommen dürfen.

Erinnern wir uns an die üblichsten Schreibweisen, die wir suchen:

  • Meier
  • Meyer
  • Mayer
  • Maier

Wir können es also genauer einschränken, wenn wir nur ganz konkret beim zweiten Zeichen ein beliebiges Zeichen zulassen (in unserem Fall a oder e), und beim dritten Zeichen erlauben wir wiederum ein beliebiges Zeichen (i oder y). Die Position 2 und 3 sind aber fix gegeben. Also müssen wir wieder mit Underscores arbeiten:

SELECT * FROM tblKunden WHERE tNachname LIKE "M__er";

Kleiner Hinweis: die Buchstaben einschränken, welche an der Position 2 vorkommen dürfen (nur e und nur a erlauben), können SQLite, MYSQL und PostgreSQL nicht. Bei Microsoft Access oder SQL-Server würde das gehen😎.

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: > < =

Lösung

SELECT * FROM tblBestellungen WHERE tBestellDatum >= DATE('1999-11-01') AND tBestellDatum <= DATE('1999-11-30')

Beachten Sie, dass bei dieser Variante die Angabe des Attributs (hier "tBestellDatum") im Teil vor dem AND, aber auch im Teil nach dem AND angegeben werden muss.

Die folgende Schreibweise, umgangssprachlich zwar verständlich, ist in SQL falsch:

SELECT * FROM tblBestellungen WHERE tBestellDatum >= DATE('1999-11-01') AND <= DATE('1999-11-30')

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!🍀

Lösung

Das ist einer der Gründe, dass Sie die Datenbank topfood.sqlite nochmals runterladen mussten hehe. Die Bestelldaten in dieser Datenbank stammen alle aus den Jahren 1999 und 2000. Ich habe das ein wenig frisiert und ein paar Daten aktualisiert😉.

Sie sollten zwei Datensätze kriegen.

Und hier der SQL-Befehl:

SELECT * FROM tblBestellungen WHERE tBestellDatum = DATE('now', 'start of month','+1 month','-1 day');

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😂😂)?

Lösung

Sie sollten drei Datensätze kriegen.

Und hier der SQL-Befehl:

SELECT * FROM tblBestellungen WHERE tBestellDatum = DATE('now', 'start of month','+2 month','-1 day');

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?

Lösung

Sie sollten 3 Datensätze erhalten.

SELECT * FROM tblBestellungen WHERE tFrachtkosten >= 150 AND tBestellDatum BETWEEN DATE('2024-01-01') AND DATE('2024-12-31');

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

Lösung

Sie sollten 3 Datensätze erhalten.

SELECT * FROM tblBestellungen WHERE tKundenID = 32 AND (tFrachtkosten >= 300 OR tFrachtkosten <5);
Previous Next

Modul Datenbanken IN EF Gymnasium Lerbermatt

Table of Contents

Inhaltsverzeichnis

  • Die WHERE-Klausel
    • Syntax von WHERE
      • Quizfrage
    • Filter für Zahlen
      • Aufgabe 1
      • Aufgabe 2
      • Vergleichsoperatoren für Zahlen
      • Aufgabe 3
    • Filter für Texte
      • Aufgabe 4
      • Der LIKE-Operator
      • Aufgabe 5
      • Aufgabe 6
      • Aufgabe 7
      • Aufgabe 8
    • Filter für Datumsangaben
      • Aufgabe 9
    • Heute vor 23 Jahren...
    • Der letzte Tag vom aktuellen Monat
      • Aufgabe 10
      • Aufgabe 11
    • Kombination von Filtern
      • Aufgabe 12
      • Aufgabe 13

Theorie

  • Grundlagen zu Datenbanken
  • Datenbank-Modelle
  • Relationale Datenbanken
  • Die Abfragesprache SQL

Installation von Software

  • Demo-Datenbank herunterladen
  • SQLite installieren
  • SQLiteStudio verwenden
  • DB Browser for SQLite verwenden

Einführung in SQL

  • Erste Schritte mit SELECT
  • ORDER BY
  • LIMIT
  • WHERE
  • GROUP BY und Aggregation
  • Weitere Berechnungen
  • SELECT vollständig

Über mehrere Tabelle abfragen

  • Was ist ein JOIN?
  • JOIN mit zwei Tabellen
  • JOIN mit drei Tabellen
  • Noch mehr JOINs 😂
  • Noch ein paar Übungen