Zurück zur StartseiteInformatik · Q1 Leistungskurs · Fach wechseln
Kostenlos starten
Q1 Leistungskurs · Informatik
Datenbanken, Datenstrukturen und Automaten in der Qualifikationsphase · Datenbanken und SQL

SQL-Abfragen über mehrere Tabellen

Eine Schulbibliothek in Köln verwaltet ihre Bücher und Autoren in getrennten Tabellen. Eine Leserin fragt: „Welche Bücher von Kehlmann haben Sie?“ Der Titel steht in einer Tabelle, der Name des Autors in einer anderen. Wie bringt man beide Informationen mit einer einzigen Abfrage zusammen? Am Ende dieser Seite können Sie diese Frage beantworten.

Einfache Abfragen auf einer Tabelle

Eine SQL-Abfrage beschreibt, was Sie wissen wollen, nicht, wie das Datenbanksystem es berechnet. Das Grundgerüst besteht aus drei Teilen. SELECT nennt die gewünschten Spalten, FROM die Tabelle und WHERE die Bedingung, die eine Zeile erfüllen muss. Mit ORDER BY sortieren Sie das Ergebnis. Das Standardverhalten ist aufsteigend (ASC), absteigend schreiben Sie DESC.

Als Beispiel dient die Tabelle Buch(ISBN, Titel, Jahr, Preis). Der Primärschlüssel ist unterstrichen gedacht, hier ISBN.

SELECT Titel, Preis

FROM Buch

WHERE Jahr >= 2005

ORDER BY Preis DESC;

Diese Abfrage liefert Titel und Preis aller Bücher ab 2005, das teuerste zuerst. Bedingungen verknüpfen Sie mit AND, OR und NOT. Vergleichsoperatoren sind =, <>, <, >, <= und >=. Zeichenketten stehen in einfachen Anführungszeichen, zum Beispiel Autor = 'Kehlmann'. Zahlen stehen ohne Anführungszeichen und mit Dezimalpunkt, zum Beispiel Preis < 9.99.

Üben★☆☆Nicht begonnen
Gegeben ist die Tabelle Buch(ISBN, Titel, Autor, Jahr, Preis). a) Schreiben Sie eine SQL-Abfrage, die alle Titel mit Erscheinungsjahr nach 2010 ausgibt. b) Schreiben Sie…

Gegeben ist die Tabelle Buch(ISBN, Titel, Autor, Jahr, Preis).

  1. a) Schreiben Sie eine SQL-Abfrage, die alle Titel mit Erscheinungsjahr nach 2010 ausgibt.
  1. b) Schreiben Sie eine Abfrage, die alle Bücher von „Kehlmann“ absteigend nach Preis sortiert ausgibt.
Lösen

Aggregatfunktionen, GROUP BY und HAVING

Oft interessiert nicht die einzelne Zeile, sondern eine Kennzahl. Dafür gibt es Aggregatfunktionen, die viele Zeilen zu einem Wert zusammenfassen: COUNT, SUM, AVG, MIN und MAX.

SELECT COUNT(*) FROM Kunde WHERE Ort = 'Münster';

Mit GROUP BY bilden Sie Gruppen von Zeilen mit gleichem Wert und berechnen die Funktion für jede Gruppe getrennt:

SELECT Ort, COUNT(*) AS Anzahl

FROM Kunde

GROUP BY Ort;

Das Ergebnis hat eine Zeile pro Ort. Nach GROUP BY dürfen im SELECT nur die Gruppierungsspalten und Aggregatfunktionen stehen.

Bedingungen an Gruppen formulieren Sie mit HAVING. WHERE filtert dagegen einzelne Zeilen vor dem Gruppieren. Die Reihenfolge, in der das Datenbanksystem die Teile auswertet, zeigt die Abbildung.

Auswertungsreihenfolge einer SQL-Abfrage: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY FROM WHERE GROUP BY HAVING SELECT ORDER BY Zeilen filtern Gruppen filtern

Daraus folgt: In WHERE darf keine Aggregatfunktion stehen, denn die Gruppen existieren zu diesem Zeitpunkt noch nicht.

Üben★☆☆Nicht begonnen
Gegeben ist Kunde(KNr, Name, Ort). a) Geben Sie eine Abfrage an, die die Anzahl der Kunden aus „Bremen“ bestimmt. b) Geben Sie eine Abfrage an, die jeden Ort mit der…

Gegeben ist Kunde(KNr, Name, Ort).

  1. a) Geben Sie eine Abfrage an, die die Anzahl der Kunden aus „Bremen“ bestimmt.
  1. b) Geben Sie eine Abfrage an, die jeden Ort mit der Anzahl seiner Kunden ausgibt.
Lösen
Üben★★☆Nicht begonnen
Gegeben ist die Tabelle Film(FNr, Titel, Jahr) mit den Zeilen (1, 'Das Boot', 1981), (2, 'Lola rennt', 1998), (3, 'Good Bye, Lenin!', 2003), und Vorstellung(VNr, FNr,…

Gegeben ist die Tabelle Film(FNr, Titel, Jahr) mit den Zeilen (1, 'Das Boot', 1981), (2, 'Lola rennt', 1998), (3, 'Good Bye, Lenin!', 2003), und Vorstellung(VNr, FNr, Kino, Besucher).

  1. a) Geben Sie das Ergebnis von SELECT Titel FROM Film WHERE Jahr > 1990 ORDER BY Titel; an.
  1. b) Schreiben Sie eine Abfrage, die für jedes Kino die Summe der Besucher für Filme vor 2000 ausgibt.
  1. c) Erläutern Sie den Unterschied zwischen WHERE und HAVING.
Lösen

Tabellen verknüpfen: der Verbund (JOIN)

Gut entworfene Datenbanken speichern jede Information nur einmal. Deshalb steht der Name eines Autors in Autor und im Buch nur dessen Nummer als Fremdschlüssel. Wollen Sie Titel und Autorenname gemeinsam ausgeben, müssen Sie die Tabellen über den Schlüssel verknüpfen. Das leistet der Verbund (JOIN).

Tabellen Autor und Buch, verbunden über die Spalte ANr (Primärschlüssel und Fremdschlüssel) Autor ANr | Name 1 | Kehlmann 2 | Funke 3 | Herrndorf 4 | Zeh Buch ISBN | Titel | ANr 101 | Die Vermessung der Welt | 1 102 | Tintenherz | 2 103 | Tschick | 3 104 | Ruhm | 1 ANr = ANr Primärschlüssel: ANr Fremdschlüssel: ANr verweist auf Autor

Die Syntax lautet:

SELECT Buch.Titel, Autor.Name

FROM Buch

JOIN Autor ON Buch.ANr = Autor.ANr;

Die Semantik lässt sich in drei Schritten beschreiben. Das System bildet erstens alle Paarungen aus je einer Zeile von Buch und einer von Autor. Es behält zweitens nur die Paare, die die ON-Bedingung erfüllen, also gleiche ANr haben. Aus diesen Zeilen wählt es drittens die Spalten des SELECT. Ein solcher Verbund heißt auch Inner Join.

Gleichwertig ist die ältere Schreibweise FROM Buch, Autor WHERE Buch.ANr = Autor.ANr. Über mehr als zwei Tabellen verbinden Sie mit weiteren JOIN … ON …. Existiert ein Spaltenname in mehreren Tabellen, setzen Sie den Tabellennamen davor (Buch.ANr). Kürzer geht es mit Alias-Namen: FROM Buch b JOIN Autor a ON b.ANr = a.ANr.

Üben★☆☆Nicht begonnen
Gegeben sind Autor(ANr, Name) und Buch(ISBN, Titel, ANr) mit Buch.ANr als Fremdschlüssel. a) Erklären Sie, was ein Verbund (JOIN) bewirkt. b) Schreiben Sie eine Abfrage,…

Gegeben sind Autor(ANr, Name) und Buch(ISBN, Titel, ANr) mit Buch.ANr als Fremdschlüssel.

  1. a) Erklären Sie, was ein Verbund (JOIN) bewirkt.
  1. b) Schreiben Sie eine Abfrage, die zu jedem Buch Titel und Autorenname ausgibt.
Lösen
Üben★★☆Nicht begonnen
Gegeben sind: Schueler(SNr, Name, Klasse), Kurs(KNr, Bezeichnung, Lehrer) und Belegung(SNr, KNr, Punkte). a) Schreiben Sie eine Abfrage, die die Namen aller Schüler…

Gegeben sind: Schueler(SNr, Name, Klasse), Kurs(KNr, Bezeichnung, Lehrer) und Belegung(SNr, KNr, Punkte).

  1. a) Schreiben Sie eine Abfrage, die die Namen aller Schüler ausgibt, die den Kurs „Informatik“ belegen.
  1. b) Schreiben Sie eine Abfrage, die für jeden Kurs die Durchschnittspunktzahl ausgibt.
  1. c) Schreiben Sie eine Abfrage, die nur Kurse mit mehr als 15 Belegungen ausgibt.
Lösen

LEFT JOIN: auch Zeilen ohne Partner

Der gewöhnliche JOIN verliert Zeilen ohne Partner. Autorin Zeh hat in unserem Beispiel kein Buch und taucht deshalb nicht im Ergebnis auf. Der LEFT JOIN behält alle Zeilen der linken Tabelle (die vor dem Schlüsselwort stehende). Gibt es keinen Partner, füllt das System die Spalten der rechten Tabelle mit NULL.

SELECT Autor.Name, Buch.Titel

FROM Autor

LEFT JOIN Buch ON Autor.ANr = Buch.ANr;
Name Titel
Kehlmann Die Vermessung der Welt
Kehlmann Ruhm
Funke Tintenherz
Herrndorf Tschick
Zeh NULL

Diese Eigenschaft nutzt man auch, um fehlende Partner zu finden: … WHERE Buch.ISBN IS NULL liefert nur Zeh. Den Vergleich mit NULL schreiben Sie immer mit IS NULL, nie mit = NULL.

Üben★★☆Nicht begonnen
Gegeben sind Kunde(KNr, Name, Ort) und Bestellung(BNr, KNr, Datum, Betrag). a) Schreiben Sie eine Abfrage, die Name und Gesamtumsatz jedes Kunden ausgibt, der mindestens…

Gegeben sind Kunde(KNr, Name, Ort) und Bestellung(BNr, KNr, Datum, Betrag).

  1. a) Schreiben Sie eine Abfrage, die Name und Gesamtumsatz jedes Kunden ausgibt, der mindestens eine Bestellung hat.
  1. b) Erklären Sie, wie sich das Ergebnis ändert, wenn auch Kunden ohne Bestellung angezeigt werden sollen, und geben Sie die passende Abfrage an (LEFT JOIN).
Lösen

Unterabfragen und zusammengesetzte Abfragen

Manchmal hängt eine Abfrage vom Ergebnis einer anderen ab. Dann setzen Sie eine Unterabfrage (Subquery) in Klammern in die Bedingung ein. Das System wertet sie zuerst aus.

Skalare Unterabfrage (liefert genau einen Wert):

SELECT Titel FROM Buch

WHERE Preis > (SELECT AVG(Preis) FROM Buch);

Mengen-Unterabfrage mit IN oder NOT IN (liefert eine Spalte mit mehreren Werten):

SELECT Name FROM Autor

WHERE ANr NOT IN (SELECT ANr FROM Buch);

Das liefert alle Autoren ohne Buch, also Zeh. Alternativ funktioniert NOT EXISTS oder der LEFT JOIN mit IS NULL.

Korrelierte Unterabfrage: Sie bezieht sich auf die äußere Zeile. Ein Beispiel ist der Vergleich eines Buchpreises mit dem Durchschnitt des eigenen Autors:

SELECT b.Titel

FROM Buch b

WHERE b.Preis > (SELECT AVG(Preis) FROM Buch

                 WHERE ANr = b.ANr);

Die Semantik als Abfolge: Das System nimmt jede Zeile b der äußeren Tabelle, berechnet für deren ANr den Durchschnitt in der inneren Abfrage und behält b, wenn die Bedingung gilt.

Eine Bedingung wie „belegt Informatik und Mathematik“ lässt sich nicht in einer einzigen Zeile prüfen. Die Spalte Bezeichnung hat in einer Zeile nur einen Wert, also kann Bezeichnung = 'Informatik' AND Bezeichnung = 'Mathematik' nie wahr werden. Sie brauchen zwei Zeilen desselben Schülers. Das erreichen Sie mit zwei IN-Unterabfragen, mit einem Verbund der Tabelle mit sich selbst (Alias-Namen) oder mit GROUP BY … HAVING COUNT(DISTINCT …) = 2.

Bei mehreren Tabellen gehen Sie am besten schrittweise vor. Erstens: Welche Spalten brauche ich, und in welchen Tabellen stehen sie? Zweitens: Über welche Schlüssel verknüpfe ich? Drittens: Welche Zeilen filtere ich mit WHERE? Viertens: Muss ich gruppieren, und welche Bedingung gilt für Gruppen? Fünftens: Wie sortiere ich?

Üben★★★Nicht begonnen
Gegeben sind Mitarbeiter(MNr, Name, Gehalt, AbtNr) und Abteilung(AbtNr, Bezeichnung, Standort). a) Schreiben Sie eine Abfrage, die die Namen der Mitarbeiter ausgibt,…

Gegeben sind Mitarbeiter(MNr, Name, Gehalt, AbtNr) und Abteilung(AbtNr, Bezeichnung, Standort).

  1. a) Schreiben Sie eine Abfrage, die die Namen der Mitarbeiter ausgibt, deren Gehalt über dem Durchschnittsgehalt ihrer eigenen Abteilung liegt (Unterabfrage).
  1. b) Schreiben Sie eine Abfrage, die für jeden Standort die Anzahl der Mitarbeiter ausgibt, aber nur für Standorte mit mindestens 10 Mitarbeitern.
  1. c) Erklären Sie die Semantik von Teilaufgabe a) als Abfolge von Auswertungsschritten.
Lösen
Üben★★★Nicht begonnen
Gegeben sind Schueler(SNr, Name), Kurs(KNr, Bezeichnung) und Belegung(SNr, KNr). a) Schreiben Sie eine Abfrage für alle Schüler, die keinen Kurs belegt haben. b)…

Gegeben sind Schueler(SNr, Name), Kurs(KNr, Bezeichnung) und Belegung(SNr, KNr).

  1. a) Schreiben Sie eine Abfrage für alle Schüler, die keinen Kurs belegt haben.
  1. b) Schreiben Sie eine Abfrage für alle Schüler, die sowohl „Informatik“ als auch „Mathematik“ belegen.
  1. c) Begründen Sie, warum die naive Bedingung Bezeichnung = 'Informatik' AND Bezeichnung = 'Mathematik' in einer einzelnen Zeile kein Ergebnis liefert.
Lösen
Üben★★★Nicht begonnen
Gegeben sind Bestellung(BNr, KNr, Datum), Position(BNr, ArtNr, Menge) und Artikel(ArtNr, Name, Preis). a) Formulieren Sie eine Abfrage, die zu jeder Bestellung den…

Gegeben sind Bestellung(BNr, KNr, Datum), Position(BNr, ArtNr, Menge) und Artikel(ArtNr, Name, Preis).

  1. a) Formulieren Sie eine Abfrage, die zu jeder Bestellung den Gesamtwert ausgibt.
  1. b) Formulieren Sie eine Abfrage, die den Artikel mit dem höchsten verkauften Gesamtumsatz ermittelt.
  1. c) Beschreiben Sie, wie sich das Ergebnis von a) verändert, wenn die Tabelle Position doppelte Zeilen enthält, und welche Konsequenz das für den Entwurf hat.
Lösen

Auf einen Blick

  • Eine SQL-Abfrage hat das Grundgerüst SELECT … FROM … WHERE … GROUP BY … HAVING … ORDER BY …. Ausgewertet wird in der Reihenfolge FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY.

  • Aggregatfunktionen (COUNT, SUM, AVG, MIN, MAX) fassen Zeilen zusammen. WHERE filtert Zeilen vor dem Gruppieren, HAVING filtert Gruppen danach.

  • Ein JOIN … ON verknüpft Tabellen über Primär- und Fremdschlüssel. Ohne Verbundbedingung entsteht das kartesische Produkt.

  • Ein LEFT JOIN behält alle Zeilen der linken Tabelle, fehlende Partner werden NULL. Mit IS NULL finden Sie Zeilen ohne Partner. Zählen Sie dann eine Spalte der rechten Tabelle.

  • Unterabfragen (skalar, mit IN/NOT IN, korreliert) lösen Aufgaben, bei denen ein Zwischenergebnis nötig ist.

  • Mit den Operatoren erläutern und analysieren beschreiben Sie Syntax und Semantik einer Abfrage Schritt für Schritt, so wie in den Beispielen oben.

Vom Anfang: Die Bibliotheksfrage lösen Sie mit einem Verbund von Buch und Autor über ANr und der Bedingung Name = 'Kehlmann'.

Alle Aufgaben zu diesem Abschnitt anzeigen