Aufwärmen · Aufgabe 1 von 7
// B2.5 · ca. 37 Min. · Einstieg
Projekt: zehn Fragen an die Bibliothek beantworten
Nach diesem Projekt übersetzen Sie eine Frage in Alltagssprache in eine Abfrage auf eine Tabelle und prüfen, ob deren Antwort wirklich die Antwort auf die Frage ist.
Lektion 5 von 5 in B2 Abfragen auf einer Tabelle
Danach können Sie
- Die Bedingungen einer Frage in eine WHERE-Klausel übersetzen, auch Muster mit LIKE und fehlende Werte mit IS NULL
- Fragen nach „dem ersten“, „den drei neuesten“ und „Seite 2“ mit ORDER BY, LIMIT und OFFSET beantworten
- Eine Antwort mit Ausdrücken, Textfunktionen und CASE formen und mit count(*) prüfen
Vorhersagen · Aufgabe 2 von 7
Sagen Sie es voraus, bevor Sie weiterlesen. Die neuesten Bücher sind Beloved (1987), Neuromancer (1984) und Kindred (1979). Was liefert dies?
SELECT title FROM books ORDER BY year DESC LIMIT 1 OFFSET 1;Üben · Aufgabe 3 von 7
Ergänzen Sie den Operator, damit die Abfrage die Autoren auflistet, deren Name einen Punkt enthält.
SELECT author FROM books WHERE author ____ '%.%' ORDER BY author;SELECT author FROM books WHERE author '%.%' ORDER BY author;Üben · Aufgabe 4 von 7
Ordnen Sie jedem Teil einer Frage den Teil der Abfrage zu, der ihn beantwortet.
Üben · Aufgabe 5 von 7
Bringen Sie die Zeilen der Antwort auf „Welches ist das neueste Sci-Fi-Buch?“ in die Reihenfolge, die SQL verlangt.
- 1.FROM books
- 2.WHERE genre = 'sci-fi'
- 3.LIMIT 1;
- 4.ORDER BY year DESC
- 5.SELECT title, year
Denksport · Aufgabe 6 von 7
Knobelaufgabe. Die Bibliothek hat The Hobbit. Was liefert dies?
SELECT count(*) FROM books WHERE title LIKE 'the%';Anwenden · Aufgabe 7 von 7
Mini-Aufgabe. Stellen Sie der Bibliothek zwei eigene Fragen und beantworten Sie jede mit einer Abfrage, zum Beispiel: „Welche Mitglieder wohnen in Berlin, nach Namen sortiert?“ und „Welches Buch hat den längsten Titel?“. Schreiben Sie vor jeder Ausführung die Antwort auf, die Sie nach den Daten erwarten; vergleichen Sie dann.
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 Beispielfragen, Schritt für Schritt beantwortet
setup.sql lädt die Bibliothek aus Modul B1: Bücher, Mitglieder und Ausleihen. main.sql beantwortet drei Beispielfragen, jede mit der Frage als Kommentar über ihrer Abfrage; die zehn Fragen der Übungen funktionieren genauso. Auf Ihrem Computer: psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sql.
main.sql
-- A. Which books have exactly one copy, A to Z?
SELECT title, copies
FROM books
WHERE copies = 1
ORDER BY title;
-- B. Which is the newest book?
SELECT title, year
FROM books
ORDER BY year DESC
LIMIT 1;
-- C. How many members live in Berlin?
SELECT count(*) AS berliners
FROM members
WHERE city = 'Berlin';
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');
CREATE TABLE loans (
id integer,
book_id integer,
member_id integer,
loaned_on date,
returned_on date
);
INSERT INTO loans VALUES
(1, 1, 1, '2026-09-01', '2026-09-10'),
(2, 3, 1, '2026-09-12', NULL),
(3, 2, 2, '2026-09-05', '2026-09-20'),
(4, 1, 3, '2026-09-15', NULL),
(5, 6, 2, '2026-09-18', NULL);
Ausführen mit
psql -X -q -v ON_ERROR_STOP=1 -f setup.sql -f main.sqlAusgabe
title | copies
-------------+--------
Beloved | 1
Emma | 1
Kindred | 1
Neuromancer | 1
(4 rows)
title | year
---------+------
Beloved | 1987
(1 row)
berliners
-----------
2
(1 row)- „Genau ein Exemplar“ wird zu WHERE copies = 1, „von A bis Z“ zu ORDER BY title.
- „Das neueste“ ist die erste Zeile nach ORDER BY year DESC; LIMIT 1 behält nur diese Zeile.
- „Wie viele“ ist count(*), das eine Zeile liefert; AS berliners benennt seine Spalte.
- Prüfen Sie jedes Ergebnis an den Daten: Ada und Linus wohnen in Berlin, 2 stimmt also.
Ä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 3
Fragen 1 bis 4: Bücher filtern, sortieren und blättern
Beantworten Sie vier Fragen, eine Abfrage je Frage, in dieser Reihenfolge. F1: Welches sind die drei ältesten Bücher (title, year, das älteste zuerst)? F2: Welche Sci-Fi-Bücher erschienen nach 1970 (title, year, das neueste zuerst)? F3: Welche Bücher haben mehr als ein Exemplar (title, copies, die meisten Exemplare zuerst)? F4: Der Katalog listet die Titel von A bis Z, zwei pro Seite: Welche Titel stehen auf Seite 2 (nur title)?
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
Hinweis 1
F1 und F4 brauchen ORDER BY vor LIMIT; F4 braucht außerdem OFFSET.
Hinweis 2
Seite 2 mit zwei Titeln pro Seite überspringt die ersten zwei Titel: OFFSET 2.
Hinweis 3
F2 hat zwei Bedingungen: genre = 'sci-fi' AND year > 1970, dann ORDER BY year DESC.
Eine Lösung zeigen
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
-- Q1. The three oldest books.
SELECT title, year
FROM books
ORDER BY year
LIMIT 3;
-- Q2. Sci-fi after 1970, newest first.
SELECT title, year
FROM books
WHERE genre = 'sci-fi' AND year > 1970
ORDER BY year DESC;
-- Q3. More than one copy, most copies first.
SELECT title, copies
FROM books
WHERE copies > 1
ORDER BY copies DESC;
-- Q4. Page 2 of the catalogue, two titles per page.
SELECT title
FROM books
ORDER BY title
LIMIT 2 OFFSET 2;
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, members and loans.
-- Replace this query with the answers to Q1 to Q4.
SELECT * FROM books ORDER BY id;
test.sql
-- test: Die vier Antworten erscheinen der Reihe nach: drei älteste, neuere Sci-Fi, mehrere Exemplare, Seite 2
-- output:
-- title | year
-- ------------+------
-- Emma | 1815
-- The Hobbit | 1937
-- Dune | 1965
-- (3 rows)
--
-- title | year
-- -------------+------
-- Neuromancer | 1984
-- Kindred | 1979
-- (2 rows)
--
-- title | copies
-- ------------+--------
-- The Hobbit | 3
-- Dune | 2
-- (2 rows)
--
-- title
-- ---------
-- Emma
-- Kindred
-- (2 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');
CREATE TABLE loans (
id integer,
book_id integer,
member_id integer,
loaned_on date,
returned_on date
);
INSERT INTO loans VALUES
(1, 1, 1, '2026-09-01', '2026-09-10'),
(2, 3, 1, '2026-09-12', NULL),
(3, 2, 2, '2026-09-05', '2026-09-20'),
(4, 1, 3, '2026-09-15', NULL),
(5, 6, 2, '2026-09-18', NULL);
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.sqlFü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 3
Fragen 5 bis 7: Muster, Text und Epochen
Beantworten Sie drei Fragen, eine Abfrage je Frage, in dieser Reihenfolge. F5: Welche Autoren schreiben ihren Namen mit einer Initiale, also mit einem Punkt (author, von A bis Z)? F6: Eine Katalogzeile pro Buch, das älteste zuerst, in einer Spalte entry: der Titel in Großbuchstaben und das Jahr in Klammern, etwa EMMA (1815). F7: Die Epoche jedes Buchs, das älteste zuerst (title, era): 'old' vor 1900, 'mid-century' vor 1970, sonst 'modern'.
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
Hinweis 1
F5: LIKE '%.%' passt auf einen Punkt irgendwo im Namen.
Hinweis 2
F6: upper(title) || ' (' || year || ')' verbindet die Teile; benennen Sie die Spalte mit AS entry.
Hinweis 3
F7: CASE prüft seine WHEN-Zweige von oben und nimmt den ersten, der wahr ist; prüfen Sie also year < 1900 vor year < 1970.
Eine Lösung zeigen
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
-- Q5. Authors who write with an initial.
SELECT author
FROM books
WHERE author LIKE '%.%'
ORDER BY author;
-- Q6. One catalogue line per book, oldest first.
SELECT upper(title) || ' (' || year || ')' AS entry
FROM books
ORDER BY year;
-- Q7. The era of each book, oldest first.
SELECT title,
CASE
WHEN year < 1900 THEN 'old'
WHEN year < 1970 THEN 'mid-century'
ELSE 'modern'
END AS era
FROM books
ORDER BY year;
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, members and loans.
-- Replace this query with the answers to Q5 to Q7.
SELECT * FROM books ORDER BY id;
test.sql
-- test: Die drei Antworten erscheinen der Reihe nach: Autoren mit Initiale, Katalogzeilen, Epochen
-- output:
-- author
-- -------------------
-- J. R. R. Tolkien
-- Octavia E. Butler
-- (2 rows)
--
-- entry
-- --------------------
-- EMMA (1815)
-- THE HOBBIT (1937)
-- DUNE (1965)
-- KINDRED (1979)
-- NEUROMANCER (1984)
-- BELOVED (1987)
-- (6 rows)
--
-- title | era
-- -------------+-------------
-- Emma | old
-- The Hobbit | mid-century
-- Dune | mid-century
-- Kindred | modern
-- Neuromancer | modern
-- Beloved | modern
-- (6 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');
CREATE TABLE loans (
id integer,
book_id integer,
member_id integer,
loaned_on date,
returned_on date
);
INSERT INTO loans VALUES
(1, 1, 1, '2026-09-01', '2026-09-10'),
(2, 3, 1, '2026-09-12', NULL),
(3, 2, 2, '2026-09-05', '2026-09-20'),
(4, 1, 3, '2026-09-15', NULL),
(5, 6, 2, '2026-09-18', NULL);
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.sqlFü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 3 von 3
Fragen 8 bis 10: Mitglieder, Lücken und offene Ausleihen
Beantworten Sie drei Fragen, eine Abfrage je Frage, in dieser Reihenfolge. F8: Welches Mitglied hat keine E-Mail (name)? F9: Wer ist 2026 oder später beigetreten, und wo wohnt er oder sie (name, dazu city, als unknown, wenn sie fehlt; wer zuerst beitrat, zuerst)? F10: Wie viele Ausleihen sind noch offen, also noch nicht zurückgegeben (eine Zahl in einer Spalte open_loans)?
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
Hinweis 1
F8 und F10 fragen nach fehlenden Werten: Nutzen Sie IS NULL, nie = NULL.
Hinweis 2
F9: joined >= '2026-01-01', und coalesce(city, 'unknown') AS city für Margaret.
Hinweis 3
F10: SELECT count(*) AS open_loans FROM loans WHERE …
Eine Lösung zeigen
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
-- Q8. Who has no email?
SELECT name
FROM members
WHERE email IS NULL;
-- Q9. Who joined in 2026, and where do they live?
SELECT name, coalesce(city, 'unknown') AS city
FROM members
WHERE joined >= '2026-01-01'
ORDER BY joined;
-- Q10. How many loans are still open?
SELECT count(*) AS open_loans
FROM loans
WHERE returned_on IS NULL;
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, members and loans.
-- Replace this query with the answers to Q8 to Q10.
SELECT * FROM members ORDER BY id;
test.sql
-- test: Die drei Antworten erscheinen der Reihe nach: Linus, die Mitglieder ab 2026, drei offene Ausleihen
-- output:
-- name
-- -------
-- Linus
-- (1 row)
--
-- name | city
-- ----------+---------
-- Linus | Berlin
-- Margaret | unknown
-- (2 rows)
--
-- open_loans
-- ------------
-- 3
-- (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');
CREATE TABLE loans (
id integer,
book_id integer,
member_id integer,
loaned_on date,
returned_on date
);
INSERT INTO loans VALUES
(1, 1, 1, '2026-09-01', '2026-09-10'),
(2, 3, 1, '2026-09-12', NULL),
(3, 2, 2, '2026-09-05', '2026-09-20'),
(4, 1, 3, '2026-09-15', NULL),
(5, 6, 2, '2026-09-18', NULL);
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.sqlFü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
LIMIT vor ORDER BY
SELECT title, year
FROM books
LIMIT 3
ORDER BY year;
Was psql ausgibt
ERROR: syntax error at or near "ORDER"Warum, und die Lösung
Die Klauseln haben eine feste Reihenfolge: SELECT, FROM, WHERE, ORDER BY, LIMIT, OFFSET. PostgreSQL liest LIMIT 3 und erwartet danach kein ORDER BY. Setzen Sie ORDER BY year über LIMIT 3; dann wird zuerst sortiert, und LIMIT behält die drei ältesten.
Auf einen CASE-Alias filtern
SELECT title,
CASE WHEN year < 1900 THEN 'old' ELSE 'new' END AS era
FROM books
WHERE era = 'old';
Was psql ausgibt
ERROR: column "era" does not existWarum, und die Lösung
era ist ein Name im Ergebnis, und WHERE arbeitet auf den Zeilen der Tabelle, bevor die Select-Liste berechnet wird. Filtern Sie auf die Spalte, die das CASE liest: WHERE year < 1900. ORDER BY era ginge, denn ORDER BY läuft nach der Select-Liste.
Eine Zählung neben einer gewöhnlichen Spalte
SELECT name, count(*)
FROM members
WHERE email IS NULL;
Was psql ausgibt
ERROR: column "members.name" must appear in the GROUP BY clause or be used in an aggregate functionWarum, und die Lösung
count(*) macht aus allen Zeilen eine Zahl, und PostgreSQL kann nicht wissen, welcher Name daneben stehen soll. Stellen Sie stattdessen zwei Fragen: SELECT name … für die Liste und SELECT count(*) … für die Zahl. Modul B3 zeigt, wie GROUP BY beides verbindet.
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.