Zum Inhalt springen
aviral gupta

// B2.1 · ca. 30 Min. · Einstieg

SELECT und WHERE

Nach dieser Lektion beantworten Sie Fragen an eine Tabelle: Sie wählen und benennen die nötigen Spalten und behalten nur die Zeilen, die eine Bedingung erfüllen.

Lektion 1 von 5 in B2 Abfragen auf einer Tabelle

Anfang des Moduls

Danach können Sie

  • Die Spalten eines Ergebnisses wählen, mit AS umbenennen und doppelte Zeilen mit DISTINCT entfernen
  • Mit WHERE, den Vergleichsoperatoren, BETWEEN und IN nur passende Zeilen behalten
  • Bedingungen mit AND, OR und NOT verknüpfen und Klammern setzen, wo die Rangfolge täuschen würde
  1. Aufwärmen · Aufgabe 1 von 7

    Aufwärmen: SELECT title FROM books WHERE year < 1900; welche Zeilen landen im Ergebnis?

  2. Vorhersagen · Aufgabe 2 von 7

    Sagen Sie es voraus, bevor Sie weiterlesen. Die Bücher stammen aus 1815, 1937, 1965, 1979, 1984 und 1987. Was liefert dies?

    SELECT count(*) FROM books WHERE year BETWEEN 1965 AND 1984;
  3. Üben · Aufgabe 3 von 7

    Ergänzen Sie das Schlüsselwort, damit die Abfrage die Klassiker und die Fantasy-Bücher auflistet.

    SELECT title FROM books WHERE genre ____ ('classic', 'fantasy') ORDER BY title;
    SELECT title FROM books WHERE genre ('classic', 'fantasy') ORDER BY title;
  4. Üben · Aufgabe 4 von 7

    Ordnen Sie jeder Bedingung zu, was sie behält.

  5. Üben · Aufgabe 5 von 7

    Bringen Sie die Klauseln dieser Abfrage in die Reihenfolge, die SQL verlangt.

    1. 1.SELECT title, year AS published
    2. 2.WHERE genre = 'sci-fi'
    3. 3.FROM books
    4. 4.ORDER BY year;
  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. Die Bibliothek hat drei Sci-Fi-Bücher (2, 1 und 1 Exemplar) und ein Fantasy-Buch (3 Exemplare). Was liefert dies?

    SELECT count(*) FROM books
    WHERE genre = 'sci-fi' OR genre = 'fantasy' AND copies > 1;
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe. Schreiben Sie mit der Bibliothek des Beispiels zwei Abfragen: Titel und Jahr der Bücher, die vor 1950 erschienen und keine Klassiker sind, und die Namen der Mitglieder in Berlin, die 2025 beigetreten sind. Führen Sie sie aus, ändern Sie dann eine Bedingung und sagen Sie das neue Ergebnis voraus, bevor Sie erneut ausführen.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Drei Fragen an die Bibliothek

setup.sql lädt die Bücher und Mitglieder der Bibliothek, die Sie in Modul B1 gebaut haben. main.sql stellt drei Fragen: Welche Sci-Fi-Bücher sind älter als 1980, welche Genres gibt es, und welche Fantasy- oder Sci-Fi-Bücher erschienen zwischen 1900 und 1980? Auf Ihrem Computer: psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sql.

main.sql

-- 1. Sci-fi books from before 1980, with the year renamed.
SELECT title, year AS published
FROM books
WHERE genre = 'sci-fi' AND year < 1980
ORDER BY year;

-- 2. Every genre, once.
SELECT DISTINCT genre FROM books ORDER BY genre;

-- 3. A range and a list in one condition.
SELECT title, genre, copies
FROM books
WHERE year BETWEEN 1900 AND 1980
  AND genre IN ('fantasy', 'sci-fi')
ORDER BY title;

setup.sql

CREATE TABLE books (
  id integer,
  title text,
  author text,
  year integer,
  genre text,
  copies integer
);

INSERT INTO books VALUES
  (1, 'Dune', 'Frank Herbert', 1965, 'sci-fi', 2),
  (2, 'Emma', 'Jane Austen', 1815, 'classic', 1),
  (3, 'Kindred', 'Octavia E. Butler', 1979, 'sci-fi', 1),
  (4, 'Beloved', 'Toni Morrison', 1987, 'fiction', 1),
  (5, 'The Hobbit', 'J. R. R. Tolkien', 1937, 'fantasy', 3),
  (6, 'Neuromancer', 'William Gibson', 1984, 'sci-fi', 1);

CREATE TABLE members (
  id integer,
  name text,
  email text,
  city text,
  joined date
);

INSERT INTO members VALUES
  (1, 'Ada', 'ada@example.com', 'Berlin', '2025-01-15'),
  (2, 'Grace', 'grace@example.com', 'Munich', '2025-03-02'),
  (3, 'Linus', NULL, 'Berlin', '2026-02-10'),
  (4, 'Margaret', 'margaret@example.com', NULL, '2026-05-20');

Ausführen mit

psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sql

Ausgabe

  title  | published
---------+-----------
 Dune    |      1965
 Kindred |      1979
(2 rows)

  genre
---------
 classic
 fantasy
 fiction
 sci-fi
(4 rows)

   title    |  genre  | copies
------------+---------+--------
 Dune       | sci-fi  |      2
 Kindred    | sci-fi  |      1
 The Hobbit | fantasy |      3
(3 rows)
  • AS published benennt die Spalte im Ergebnis um; in der Tabelle heißt sie weiter year.
  • Auch Neuromancer ist Sci-Fi, doch 1984 ist nicht < 1980, deshalb lässt die erste Abfrage es weg.
  • DISTINCT macht aus sechs Zeilen vier: sci-fi erscheint nur einmal.
  • BETWEEN 1900 AND 1980 lässt Emma (1815) weg, IN lässt Beloved (fiction) weg.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser PostgreSQL herunter (bis zu 10.1 MB) und speichert es im Cache. Jeder Lauf beginnt mit einer leeren Datenbank. Ihr Code bleibt auf Ihrem Gerät.

Übungen

Übung 1 von 2

Sci-Fi vor 1980 und die Genres mit einem Exemplar

Schreiben Sie zwei Abfragen. Erstens: Titel und Autor, benannt als writer, jedes Sci-Fi-Buchs, das vor 1980 erschien, das älteste zuerst. Zweitens: jedes Genre, das ein Buch mit genau einem Exemplar hat, jeweils einmal, alphabetisch sortiert.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser PostgreSQL herunter (bis zu 10.1 MB) und speichert es im Cache. Jeder Lauf beginnt mit einer leeren Datenbank. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    Zwei Bedingungen, verbunden mit AND: genre = 'sci-fi' und year < 1980.

  2. Hinweis 2

    author AS writer benennt die Spalte im Ergebnis um.

  3. Hinweis 3

    SELECT DISTINCT genre … WHERE copies = 1 ORDER BY genre; listet jedes Genre einmal.

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

SELECT title, author AS writer
FROM books
WHERE genre = 'sci-fi' AND year < 1980
ORDER BY year;

SELECT DISTINCT genre
FROM books
WHERE copies = 1
ORDER BY genre;
Auf dem eigenen Computer ausführen

Installieren Sie PostgreSQL 18 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.sql

-- setup.sql has loaded books and members.
SELECT * FROM books ORDER BY id;

test.sql

-- test: Die zwei Abfragen geben die Sci-Fi-Bücher mit ihren Autoren aus, dann die Genres mit einem Exemplar
-- output:
--   title  |      writer
-- ---------+-------------------
--  Dune    | Frank Herbert
--  Kindred | Octavia E. Butler
-- (2 rows)
--
--   genre
-- ---------
--  classic
--  fiction
--  sci-fi
-- (3 rows)

setup.sql

CREATE TABLE books (
  id integer,
  title text,
  author text,
  year integer,
  genre text,
  copies integer
);

INSERT INTO books VALUES
  (1, 'Dune', 'Frank Herbert', 1965, 'sci-fi', 2),
  (2, 'Emma', 'Jane Austen', 1815, 'classic', 1),
  (3, 'Kindred', 'Octavia E. Butler', 1979, 'sci-fi', 1),
  (4, 'Beloved', 'Toni Morrison', 1987, 'fiction', 1),
  (5, 'The Hobbit', 'J. R. R. Tolkien', 1937, 'fantasy', 3),
  (6, 'Neuromancer', 'William Gibson', 1984, 'sci-fi', 1);

CREATE TABLE members (
  id integer,
  name text,
  email text,
  city text,
  joined date
);

INSERT INTO members VALUES
  (1, 'Ada', 'ada@example.com', 'Berlin', '2025-01-15'),
  (2, 'Grace', 'grace@example.com', 'Munich', '2025-03-02'),
  (3, 'Linus', NULL, 'Berlin', '2026-02-10'),
  (4, 'Margaret', 'margaret@example.com', NULL, '2026-05-20');

psql führt die Dateien auf Ihrem eigenen PostgreSQL-Server aus. Nehmen Sie eine leere Datenbank, die Sie wegwerfen können: Hängen Sie -d und ihren Namen an den Befehl an.

Programm ausführen:

psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sql

Für die Prüfungen gibt es auf Ihrem Computer noch keinen Befehl. Sie stehen in test.sql: Jede Prüfabfrage gibt t aus, wenn sie besteht.

Übung 2 von 2

Die Einladungsliste reparieren

Die Vorlage soll die Mitglieder in Berlin oder München auflisten, die am oder nach dem 1. Januar 2026 beigetreten sind, listet aber auch Ada, die 2025 beitrat. Finden Sie den Grund und reparieren Sie die Bedingung; die Spalten name, city und joined und die Sortierung nach id bleiben. Probieren Sie beide Reparaturen: Klammern und IN.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser PostgreSQL herunter (bis zu 10.1 MB) und speichert es im Cache. Jeder Lauf beginnt mit einer leeren Datenbank. Ihr Code bleibt auf Ihrem Gerät.

Hinweise
  1. Hinweis 1

    AND bindet vor OR. Zu welchem Teil der Bedingung gehört joined >= …?

  2. Hinweis 2

    Setzen Sie die beiden Städte in Klammern: (city = 'Berlin' OR city = 'Munich') AND …

  3. Hinweis 3

    Oder ersetzen Sie die beiden Vergleiche durch city IN ('Berlin', 'Munich').

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

-- Members in Berlin or Munich who joined in 2026 or later.
SELECT name, city, joined
FROM members
WHERE city IN ('Berlin', 'Munich') AND joined >= '2026-01-01'
ORDER BY id;
Auf dem eigenen Computer ausführen

Installieren Sie PostgreSQL 18 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.sql

-- Members in Berlin or Munich who joined in 2026 or later.
SELECT name, city, joined
FROM members
WHERE city = 'Berlin' OR city = 'Munich' AND joined >= '2026-01-01'
ORDER BY id;

test.sql

-- test: Nur Linus steht auf der Liste: Berlin, beigetreten am 2026-02-10
-- output:
--  name  |  city  |   joined
-- -------+--------+------------
--  Linus | Berlin | 2026-02-10
-- (1 row)

setup.sql

CREATE TABLE books (
  id integer,
  title text,
  author text,
  year integer,
  genre text,
  copies integer
);

INSERT INTO books VALUES
  (1, 'Dune', 'Frank Herbert', 1965, 'sci-fi', 2),
  (2, 'Emma', 'Jane Austen', 1815, 'classic', 1),
  (3, 'Kindred', 'Octavia E. Butler', 1979, 'sci-fi', 1),
  (4, 'Beloved', 'Toni Morrison', 1987, 'fiction', 1),
  (5, 'The Hobbit', 'J. R. R. Tolkien', 1937, 'fantasy', 3),
  (6, 'Neuromancer', 'William Gibson', 1984, 'sci-fi', 1);

CREATE TABLE members (
  id integer,
  name text,
  email text,
  city text,
  joined date
);

INSERT INTO members VALUES
  (1, 'Ada', 'ada@example.com', 'Berlin', '2025-01-15'),
  (2, 'Grace', 'grace@example.com', 'Munich', '2025-03-02'),
  (3, 'Linus', NULL, 'Berlin', '2026-02-10'),
  (4, 'Margaret', 'margaret@example.com', NULL, '2026-05-20');

psql führt die Dateien auf Ihrem eigenen PostgreSQL-Server aus. Nehmen Sie eine leere Datenbank, die Sie wegwerfen können: Hängen Sie -d und ihren Namen an den Befehl an.

Programm ausführen:

psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sql

Für die Prüfungen gibt es auf Ihrem Computer noch keinen Befehl. Sie stehen in test.sql: Jede Prüfabfrage gibt t aus, wenn sie besteht.

Häufige Fehler

Text ohne Anführungszeichen

SELECT title FROM books WHERE genre = sci-fi;

Was psql ausgibt

ERROR:  column "sci" does not exist

Warum, und die Lösung

Ohne Anführungszeichen wird sci-fi als Ausdruck gelesen: eine Spalte sci minus eine Spalte fi. Eine Spalte sci gibt es nicht, und genau die nennt der Fehler. Textwerte stehen immer in einfachen Anführungszeichen: WHERE genre = 'sci-fi'.

Einen Spaltenalias in WHERE verwenden

SELECT title, year AS published
FROM books
WHERE published > 1980;

Was psql ausgibt

ERROR:  column "published" does not exist

Warum, und die Lösung

AS benennt eine Spalte des Ergebnisses, und das Ergebnis entsteht aus den Zeilen, die WHERE schon behalten hat. WHERE schaut auf die Tabelle, in der die Spalte noch year heißt. Filtern Sie auf die Spalte selbst: WHERE year > 1980. ORDER BY, das zuletzt läuft, darf den Alias verwenden.

== aus einer anderen Sprache

SELECT title FROM books WHERE genre == 'sci-fi';

Was psql ausgibt

ERROR:  operator does not exist: text == unknown

Warum, und die Lösung

In SQL ist Gleichheit ein einfaches =. PostgreSQL hat keinen Operator == für Text und sagt das auch: Es suchte einen Operator == zwischen einer text-Spalte und einem Wert in Anführungszeichen vom Typ unknown und fand keinen. Schreiben Sie genre = 'sci-fi'. Ungleich ist <> (oder !=).

PostgreSQL im Browser: PGlite 0.5.8 (PostgreSQL 18.3), Apache-2.0 und PostgreSQL License. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

Die Select-Liste bestimmt die Spalten

SELECT title, year FROM books liefert zwei Spalten in dieser Reihenfolge; SELECT * liefert alle. Jeder Eintrag darf auch ein Ausdruck sein, etwa copies * 2. AS gibt einer Ergebnisspalte einen neuen Namen: SELECT year AS published. Der Name gehört nur zum Ergebnis; WHERE, das die Zeilen der Tabelle prüft, kennt ihn nicht: WHERE published > 1980 scheitert mit column "published" does not exist. SELECT DISTINCT genre entfernt doppelte Zeilen aus dem Ergebnis, nachdem die Select-Liste gebildet ist: Zwei Zeilen gelten nur als gleich, wenn jede gewählte Spalte gleich ist. DISTINCT sortiert nicht; nehmen Sie ORDER BY dazu, wenn die Reihenfolge zählt.

WHERE behält die Zeilen, für die die Bedingung wahr ist

WHERE prüft jede Zeile und behält sie nur, wenn ihre Bedingung wahr ist. Die Vergleichsoperatoren sind = (gleich), <> oder != (ungleich), <, >, <= und >=. Sie funktionieren mit Zahlen, mit Text (exakt verglichen, 'Sci-Fi' ist also nicht 'sci-fi') und mit Daten ('2026-01-01' in Anführungszeichen). year BETWEEN 1937 AND 1979 ist die Kurzform von year >= 1937 AND year <= 1979: Beide Enden gehören dazu. genre IN ('sci-fi', 'fantasy') ist kurz für genre = 'sci-fi' OR genre = 'fantasy', und NOT IN behält den Rest. Eine Kette wie 1900 < year < 2000 ist nicht erlaubt; schreiben Sie year > 1900 AND year < 2000 oder BETWEEN.

AND bindet vor OR: Setzen Sie Klammern

AND, OR und NOT verknüpfen Bedingungen. Wie Punkt vor Strich in der Arithmetik bindet NOT zuerst, dann AND, dann OR. city = 'Berlin' OR city = 'Munich' AND joined >= '2026-01-01' bedeutet also Berlin (beliebiges Datum) oder (München und 2026), was selten die gestellte Frage ist. Klammern machen die Gruppierung ausdrücklich: (city = 'Berlin' OR city = 'Munich') AND joined >= '2026-01-01'. Oft erspart IN die Klammern: city IN ('Berlin', 'Munich') AND joined >= '2026-01-01'. Mischt eine Bedingung AND und OR, schreiben Sie die Klammern auch dort, wo sie nichts ändern: Wer den Code liest, muss dann die Rangfolge nicht im Kopf haben.

Quellen

Zuletzt geprüft am 30. September 2026