Direkt zum Inhalt

BPE 6 · J1

Mehrere Tabellen mit JOIN verbinden

Du verknüpfst Stammdaten und Zuordnungen über ihre Schlüssel und erstellst auch Übersichten, die Personen oder Kurse ohne Treffer enthalten.

Bildungsplanbezug: BPE 6.4 · interne Lerneinheit 6.2.6

Geschätzte Lernzeit: 65 Minuten

Noch nicht begonnen

Das kannst du danach

  • Tabellen über Schlüssel und Fremdschlüssel verbinden
  • n:m-Beziehungen über eine Zuordnungstabelle abfragen
  • INNER JOIN und LEFT JOIN unterscheiden
  • fehlende Treffer, Duplikate und Zählungen korrekt behandeln

Verständlich erklärt

JOIN kombiniert passende Zeilen anhand der ON-Bedingung. INNER JOIN übernimmt nur Kombinationen mit einem Treffer auf beiden Seiten. LEFT JOIN erhält jede Zeile der linken Tabelle; ohne rechten Treffer stehen die rechten Spalten auf NULL. In einer n:m-Beziehung führt der Weg durch die Zuordnungstabelle. Eine Person mit mehreren Anmeldungen erscheint entsprechend mehrfach. Nutze DISTINCT nur, wenn fachlich jede Person einmal gewünscht ist. Nach LEFT JOIN zählt COUNT(rechter_schluessel) echte Treffer; COUNT(*) würde auch die erhaltene Zeile ohne Treffer zählen. Ein Filter auf der rechten Tabelle gehört bei erhaltener linker Grundmenge häufig in ON, nicht in WHERE.

  • INNER JOIN
  • LEFT JOIN
  • ON
  • Tabellenalias
  • Fremdschlüssel
  • Zuordnungstabelle

Beispiel

SELECT k.titel, COUNT(a.person_id) AS anmeldungen
FROM kurs AS k
LEFT JOIN anmeldung AS a ON a.kurs_id = k.id
GROUP BY k.id, k.titel
ORDER BY k.id;

Typische Fehler

  • Gleichnamige IDs ohne die Fremdschlüsselbeziehung verbinden
  • Die ON-Bedingung weglassen und ein kartesisches Produkt erzeugen
  • LEFT JOIN mit einem WHERE-Filter auf rechte Spalten unbeabsichtigt einschränken
  • COUNT(*) für eine Trefferanzahl inklusive Nulltreffern verwenden

Kurz zusammengefasst

Wähle zuerst die fachliche Grundmenge und danach die JOIN-Art. Schlüssel legen die Verbindung fest; eine n:m-Zuordnung erzeugt bewusst mehrere passende Ergebniszeilen.

Abi-Bezug

Entwickle Mehrtabellenabfragen aus einem relationalen Modell und erkläre die Auswirkungen der JOIN-Art auf fehlende Zuordnungen und Mehrfachtreffer.

Jetzt selbst ausprobieren

Prüfe deine Lösung automatisch. Bei Bedarf helfen dir ein Tipp und anschließend die Musterlösung.

BPE 6J11 Punkteleicht

Personennamen zu Anmeldungen

Noch nicht begonnen

Aufgabenstellung

Zeige für jede Anmeldung den Namen der Person und die Kurs-ID. Personen mit mehreren Anmeldungen erscheinen mehrfach; Personen ohne Anmeldung erscheinen nicht.

Ergebnisspalten in dieser Reihenfolge: name, kurs_id. Die Zeilenreihenfolge ist hier beliebig. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. anmeldung.person_id verweist auf person.id.
  2. Die ON-Bedingung verhindert, dass jede Person mit jeder Anmeldung kombiniert wird.
Lösung anzeigen
SELECT p.name, a.kurs_id FROM person AS p INNER JOIN anmeldung AS a ON a.person_id = p.id;
BPE 6J11 Punkteleicht

Die n:m-Beziehung lesbar ausgeben

Noch nicht begonnen

Aufgabenstellung

Zeige zu jeder Anmeldung den Namen der Person und den Kurstitel. Verwende die Zuordnungstabelle zwischen person und kurs. Jede Anmeldung bleibt eine eigene Ergebniszeile.

Ergebnisspalten in dieser Reihenfolge: name, titel. Die Zeilenreihenfolge ist hier beliebig. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. Der Weg geht von person über anmeldung zu kurs.
  2. Für jeden der beiden JOIN-Schritte wird eine eigene Schlüsselbedingung benötigt.
Lösung anzeigen
SELECT p.name, k.titel FROM person AS p JOIN anmeldung AS a ON a.person_id = p.id JOIN kurs AS k ON k.id = a.kurs_id;
BPE 6J12 Punktemittel

Punkte im SQL-Kurs

Noch nicht begonnen

Aufgabenstellung

Zeige die Namen und Punkte aller für den Kurs mit Titel SQL angemeldeten Personen. Eine Anmeldung ohne Bewertung bleibt enthalten und zeigt NULL.

Ergebnisspalten in dieser Reihenfolge: name, punkte. Die Zeilenreihenfolge ist hier beliebig. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. Verbinde zusätzlich kurs, damit der Titel gefiltert werden kann.
  2. Der Filter betrifft den Kurstitel, nicht das Vorhandensein einer Bewertung.
Lösung anzeigen
SELECT p.name, a.punkte FROM person AS p JOIN anmeldung AS a ON p.id = a.person_id JOIN kurs AS k ON k.id = a.kurs_id WHERE k.titel = 'SQL';
BPE 6J12 Punktemittel

Alle Personen, auch ohne Anmeldung

Noch nicht begonnen

Aufgabenstellung

Zeige jeden Personennamen mit den jeweiligen Kurs-IDs. Eine Person mit mehreren Anmeldungen erscheint mehrfach. Eine Person ohne Anmeldung erscheint einmal mit NULL als Kurs-ID.

Ergebnisspalten in dieser Reihenfolge: name, kurs_id. Die Zeilenreihenfolge ist hier beliebig. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. person ist die Tabelle, deren vollständige Zeilenmenge erhalten bleiben soll.
  2. LEFT JOIN ergänzt für fehlende rechte Treffer NULL-Werte.
Lösung anzeigen
SELECT p.name, a.kurs_id FROM person AS p LEFT JOIN anmeldung AS a ON p.id = a.person_id;
BPE 6J12 Punktemittel

Kursbelegung einschließlich leerer Kurse

Noch nicht begonnen

Aufgabenstellung

Gib für jeden Kurs den Titel und die Anzahl der Anmeldungen als anzahl aus. Ein Kurs ohne Anmeldung muss die Anzahl 0 erhalten. Sortiere nach Kurs-ID aufsteigend.

Ergebnisspalten in dieser Reihenfolge: titel, anzahl. Die angegebene Zeilensortierung wird geprüft. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. LEFT JOIN erhält auch den Kurs Datenmodell.
  2. COUNT(a.person_id) zählt nur echte Anmeldungen; COUNT(*) würde auch die Nulltrefferzeile zählen.
Lösung anzeigen
SELECT k.titel, COUNT(a.person_id) AS anzahl FROM kurs AS k LEFT JOIN anmeldung AS a ON a.kurs_id = k.id GROUP BY k.id, k.titel ORDER BY k.id ASC;
BPE 6J12 Punktemittel

Personen ohne jede Anmeldung

Noch nicht begonnen

Aufgabenstellung

Finde ausschließlich Personen ohne eine einzige Anmeldung. Gib ihre Namen aus.

Ergebnisspalten in dieser Reihenfolge: name. Die Zeilenreihenfolge ist hier beliebig. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. Nach LEFT JOIN haben Personen ohne Treffer NULL in a.person_id.
  2. Prüfe den rechten Schlüssel, nicht punkte: Fehlende Punkte können auch bei vorhandenen Anmeldungen vorkommen.
Lösung anzeigen
SELECT p.name FROM person AS p LEFT JOIN anmeldung AS a ON a.person_id = p.id WHERE a.person_id IS NULL;
BPE 6J13 Punkteanspruchsvoll

Leistungsnachweis ohne doppelte Namen

Noch nicht begonnen

Aufgabenstellung

Gib die Namen aller Personen aus, die in mindestens einer Anmeldung 12 oder mehr Punkte haben. Jede Person soll hier genau einmal erscheinen; in diesen Startdaten sind die Namen eindeutig.

Ergebnisspalten in dieser Reihenfolge: name. Die Zeilenreihenfolge ist hier beliebig. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. Cem erfüllt die Punktgrenze in zwei Anmeldungen.
  2. DISTINCT entfernt identische Namenszeilen aus der gefilterten Ausgabe.
Lösung anzeigen
SELECT DISTINCT p.name FROM person AS p JOIN anmeldung AS a ON a.person_id = p.id WHERE a.punkte >= 12;
BPE 6J13 Punkteanspruchsvoll

Gute Ergebnisse je Kurs, Nulltreffer erhalten

Noch nicht begonnen

Aufgabenstellung

Zeige jeden Kurstitel und die Anzahl der Anmeldungen mit mindestens 12 Punkten als anzahl. Auch Kurse ohne passende Anmeldung müssen mit 0 erscheinen. Sortiere nach Kurs-ID aufsteigend.

Ergebnisspalten in dieser Reihenfolge: titel, anzahl. Die angegebene Zeilensortierung wird geprüft. Gib genau diese eine Ergebnistabelle aus.

Datenbankschema und vollständige Startdaten anzeigen

Fiktive Übungsdaten. Jeder Test startet neu mit genau diesen Daten. NULL bedeutet: kein Wert gespeichert. Preise und Beträge sind ganze Euro; das Datum hat das Format JJJJ-MM-TT.

CREATE TABLE person (id INTEGER PRIMARY KEY, name TEXT NOT NULL, ort TEXT NOT NULL);
Startdaten: person
idnameort
1AylinUlm
2BenUlm
3CemBaden
4DanaBaden
CREATE TABLE kurs (id INTEGER PRIMARY KEY, titel TEXT NOT NULL);
Startdaten: kurs
idtitel
1SQL
2Python
3Datenmodell
CREATE TABLE anmeldung (person_id INTEGER NOT NULL REFERENCES person(id), kurs_id INTEGER NOT NULL REFERENCES kurs(id), punkte INTEGER, PRIMARY KEY (person_id, kurs_id));
Startdaten: anmeldung
person_idkurs_idpunkte
1112
129
21NULL
3215
3112

Ausgabe bzw. Vorschau

Noch nicht ausgeführt.
2 Tipps anzeigen
  1. Beschränke die rechten Treffer bereits in ON auf mindestens 12 Punkte.
  2. Ein WHERE-Filter auf a.punkte würde die Nulltrefferzeile des leeren Kurses entfernen.
Lösung anzeigen
SELECT k.titel, COUNT(a.person_id) AS anzahl FROM kurs AS k LEFT JOIN anmeldung AS a ON a.kurs_id = k.id AND a.punkte >= 12 GROUP BY k.id, k.titel ORDER BY k.id ASC;

Lektionsabschluss

Bearbeite Aufgaben, um deine Auswertung zu sehen.