Qualifikationsphase Q2 · Themenfeld Q2.2

Q2.2 – SQL

Daten mit der Structured Query Language abfragen, auswerten und bearbeiten

In Q2.1 wurden fachliche Zusammenhänge als relationale Struktur modelliert. Q2.2 zeigt nun die zugehörige Arbeitssprache: SQL.

SQL dient nicht nur zum Anzeigen von Daten. Es unterstützt auch Auswertung, Verknüpfung und kontrollierte Bearbeitung von Datensätzen in den Tabellen, die über Primärschlüssel und Fremdschlüssel verbunden sind.

Kerncurriculum
Kerncurriculum kompakt
Einordnung und Lernziele des Themenfelds Q2.2

A) Allgemeine Einordnung

Q2.2 schließt direkt an Q2.1 an: Aus der relationalen Datenstruktur wird nun die operative Arbeit mit Datenbeständen. SQL ist dabei die zentrale Arbeitssprache, um Informationen gezielt auszulesen, auszuwerten und kontrolliert zu verändern.

Die Kompetenzentwicklung folgt einer klaren Progression: Selektion und Projektion bilden den Einstieg, danach folgen Aggregation, JOIN, GROUP BY/HAVING, Unterabfragen und die konzeptionelle Einordnung von DML.

B) Anforderungen nach Kursniveau

Grundlegendes Niveau

Im grundlegenden Niveau werden tragfähige SELECT-Strategien aufgebaut. Dazu gehören Projektion (Spaltenauswahl) und Selektion (Filterung mit WHERE) als Basismuster jeder Abfrage.

Darauf aufbauend nutzen Lernende Aggregatfunktionen zur Verdichtung, JOIN zur Verknüpfung mehrerer Tabellen, Sortierung über ORDER BY sowie Gruppierung mit GROUP BY und HAVING für auswertende Fragestellungen.

Erhöhtes Niveau (Leistungskurs)

Im erhöhten Niveau werden weiterführende SELECT-Abfragen entwickelt: insbesondere Unterabfragen und komplexere, verschachtelte Abfragelogik über mehrere Bedingungen und Auswertungsebenen.

Zusätzlich werden weitere SQL-Sprachbereiche eingeordnet: DML (INSERT, UPDATE, DELETE) zur Datenbearbeitung, DDL (z. B. CREATE TABLE) konzeptionell zur Strukturdefinition sowie optional DCL als Überblick über Berechtigungssteuerung. Diese Bereiche werden fachlich eingeordnet; im Werkzeug werden sie nicht als ausführbare Aufgaben angeboten.

C) Aufgabenmarkierungen im SQL-Werkzeug

GK, GK+ und LK im SELECT-Editor

Die Übungsaufgaben im SQL-Werkzeug sind reine SELECT-Aufgaben. Die Markierung GK bezeichnet grundlegende SELECT-Kompetenzen: Projektion, Selektion, Sortierung, einfache Aggregation, einfache Joins sowie Grundlagen von GROUP BY und HAVING.

GK+ markiert anspruchsvollere Übungs- und Transfermuster, etwa mehrstufige Joins, LEFT JOIN, Gruppierung über mehrere Tabellen, HAVING, berechnete Spalten, Status- und Vorgangslogik sowie einfache Negationsmuster mit NOT EXISTS.

LK beschreibt erhöhtes Niveau innerhalb des SELECT-Editors nicht einfach als höhere Schwierigkeit, sondern als Kombination aus komplexeren Modellpfaden, korrelierten Unterabfragen, dynamischen Vergleichswerten, rekursiven Beziehungen beziehungsweise Self-Joins, Unterabfragen in HAVING sowie Bedarfs-, Bestands- oder Vollständigkeitslogik.

Einfache Negationsmuster mit NOT EXISTS werden im Werkzeug häufig als GK+ geführt. LK wird dort markiert, wo die Negation mit längeren Modellpfaden, rekursiven Beziehungen oder dynamischen Auswertungsebenen verbunden wird. DML, DDL und DCL gehören fachlich zum erweiterten SQL-Begriff, werden im aktuellen Aufgabenpool aber nicht als ausführbare Aufgaben angeboten.

Drei Datenbanken im Aufgabenpool

Die Schulbibliothek baut die Grundoperationen systematisch auf: SELECT, WHERE, Sortierung, Aggregation, JOIN, GROUP BY, HAVING und erste Transfermuster.

Die Medienwerkstatt erweitert diese Muster auf Betriebs-, Status-, Vorgangs- und Verfügbarkeitslogik. Dadurch werden aus einzelnen Abfragemustern fachliche Entscheidungen über Geräte, Projekte, Bestellungen, Wartung und Qualität.

Die Projektmesse ist kein weiterer Einstieg in SQL, sondern ein Anschlussmodul: Bereits bekannte SELECT-Muster werden dort in komplexeren Modellpfaden, Spezialisierungen, optionalen Zuordnungen, Bewertungssystemen, dynamischen Auswertungen, rekursiven Beziehungen und korrelierten Unterabfragen verwendet.

SQL-Abfragen
Daten mit SQL abfragen
SELECT, FROM, WHERE und grundlegende Filterung

Wir arbeiten auf dieser Inhaltsseite durchgehend mit einem reduzierten Mini-Schema für Seitenbeispiele aus dem Q2.1-Kontext „Buchhandel/Schulbibliothek":

buch(id, titel, preis, bestand, verlag_id)
autor(id, name)
schreibt(buch_id, autor_id)
verlag(id, name, ort)
kurs(id, bezeichnung, lehrkraft)
leihe(id, buch_id, kurs_id, rueckgabedatum)

Dieses Mini-Schema hält die Beispiele lesbar und ist bewusst didaktisch reduziert. Das SQL-Werkzeug arbeitet mit konkreteren Übungsdatenbanken. In der Schulbibliothek gelten unter anderem BUCH, AUTOR(Vorname, Nachname), BUCH_AUTOR, EXEMPLAR, AUSLEIHE und NUTZER. Besonders wichtig: Im Werkzeug besitzt AUTOR in der Schulbibliothek Vorname und Nachname, nicht Name. Die gleiche Abfragelogik wird dort auf die konkreten Tabellen- und Feldnamen wie BuchID, AutorID oder ExemplarID übertragen.

Lokale SQL-Begriffe

Eine Relation erscheint in SQL praktisch als Tabelle. Attribute werden als Spaltennamen angesprochen, Tupel beziehungsweise Datensätze als Zeilen. Eine SQL-Abfrage erzeugt aus solchen Tabellen wieder eine tabellenartige Ergebnisrelation.

Deklaratives Prinzip

SQL beschreibt, welches Ergebnis benötigt wird. Das Datenbanksystem entscheidet intern, wie dieses Ergebnis effizient erzeugt wird.

Für die Grundlogik einer SELECT-Anfrage ist die Unterscheidung zentral: Projektion legt fest, welche Spalten angezeigt werden, und Selektion legt fest, welche Zeilen in das Ergebnis gelangen. Erst das Zusammenspiel beider Schritte erzeugt fachlich präzise Datensichten. Projektion und Selektion sind formale Begriffe der Relationenalgebra; in Q2.2 stehen sie als praktische SQL-Bewegung für Spaltenauswahl und Zeilenfilterung.

1) Grundform der SELECT-Abfrage

SELECT titel, preis
FROM buch
WHERE preis <= 20.00;
titel preis
SQL im Unterricht19.90
Netzwerke kompakt14.50
Algorithmik verstehen17.80
Informatik 112.00

Die Abfrage zeigt alle Bücher mit einem Preis von höchstens 20,00 €.

SELECT wählt die Attribute beziehungsweise Ergebnisspalten, FROM benennt die Relation oder Tabelle und WHERE formuliert Bedingungen für die Auswahl von Datensätzen. Das Ergebnis ist wieder eine tabellenartige Ergebnisrelation. Syntax beschreibt, wie die Abfrage korrekt notiert wird; Semantik beschreibt, welche Wirkung die Abfrage auf den Datenbestand hat und welche Ergebnisrelation entsteht.

2) Spaltenwahl, * und Vergleichsoperatoren

SELECT *
FROM buch;

SELECT titel, bestand
FROM buch
WHERE bestand < 5;
id titel preis bestand verlag_id
12Datenbanken Basiswissen24.9031
18Informatik 112.0023
27Robotik Projekte29.5045

SELECT * liefert alle Spalten; die zweite Abfrage filtert daraus Bücher mit kleinem Bestand.

Vergleichsoperatoren in WHERE: =, <>, <, >, <=, >=.

Die WHERE-Klausel ist das zentrale Filterinstrument für Zeilen. Ohne WHERE bezieht sich eine SELECT-Anfrage auf alle Datensätze der gewählten Tabelle; mit WHERE wird die Ergebnismenge fachlich begründet eingeschränkt.

3) Logische Operatoren AND, OR, NOT

SELECT titel, preis, bestand
FROM buch
WHERE preis < 15
  AND bestand > 0;

SELECT titel
FROM buch
WHERE titel LIKE 'Daten%'
   OR titel LIKE 'Informatik%';

SELECT titel
FROM buch
WHERE NOT bestand = 0;
titel
Informatik 1
Datenstrukturen verstehen
SQL im Unterricht
Algorithmik verstehen

Die gezeigten Filter verknüpfen Bedingungen und schließen nur Titel mit Bestand 0 aus.

4) Bereichs-, Muster- und Listenfilter

-- BETWEEN (inklusive Grenzen)
SELECT titel, preis
FROM buch
WHERE preis BETWEEN 10 AND 25;

-- LIKE (% = Zeichenfolge, _ = genau ein Zeichen)
SELECT name
FROM autor
WHERE name LIKE 'M%';

-- IN mit Werteliste
SELECT titel, verlag_id
FROM buch
WHERE verlag_id IN (1, 3, 5);
titel verlag_id
Datenbanken Basiswissen1
Informatik 13
Robotik Projekte5
Datenstrukturen verstehen1

Bei IN bleiben nur Bücher aus den ausgewählten Verlagen im Ergebnis.

LIKE eignet sich für Mustervergleiche in Textfeldern, IN für feste Wertemengen und BETWEEN für zusammenhängende Intervalle. Diese drei Varianten decken typische schulische Suchsituationen ab und machen Filterbedingungen lesbarer als lange Ketten mit OR.

5) NULL-Prüfung

SELECT id, buch_id, kurs_id
FROM leihe
WHERE rueckgabedatum IS NULL;
id buch_id kurs_id
301187
3092711
312127

IS NULL markiert aktuell noch nicht zurückgegebene Ausleihen.

NULL bedeutet „kein eingetragener Wert“ und ist nicht dasselbe wie 0 oder ein leerer String. Deshalb wird mit IS NULL beziehungsweise IS NOT NULL geprüft und nicht mit = NULL.

6) DISTINCT, AS, ORDER BY, LIMIT

SELECT DISTINCT verlag_id
FROM buch;

SELECT titel AS buchtitel, preis AS europreis
FROM buch
ORDER BY europreis DESC, buchtitel ASC
LIMIT 5;

SELECT titel, preis
FROM buch
ORDER BY preis ASC
LIMIT 3, 4;
buchtitel europreis
Robotik Projekte29.50
Datenbanken Basiswissen24.90
SQL im Unterricht19.90
Algorithmik verstehen17.80
Netzwerke kompakt14.50

Aliasnamen, Sortierung und LIMIT machen den Ausgabeausschnitt klar strukturiert.

DISTINCT entfernt Dubletten in der Ausgabe, AS sorgt für klare Spaltenbezeichnungen, ORDER BY macht Reihenfolgen nachvollziehbar und LIMIT begrenzt Ergebnismengen auf einen didaktisch sinnvollen Ausschnitt. Aliasnamen sind vor allem für die Ergebnisdarstellung hilfreich; im Übungswerkzeug ist meist nicht der Aliasname selbst prüfentscheidend, sondern ob Werte und Ergebnisstruktur zur Aufgabe passen.

Didaktische Leitfrage

Eine gute SELECT-Anfrage beginnt nicht mit einem Befehl, sondern mit einer präzisen Frage: Welche Information wird für welche Entscheidung benötigt?

Aggregatfunktionen
Daten auswerten mit Aggregatfunktionen
COUNT, SUM, MIN, MAX und AVG

Aggregatfunktionen verdichten viele Zeilen zu einem Kennwert. Damit wechselt die Perspektive von der Einzeldatensatzsicht zur zusammenfassenden Auswertung.

Damit entsteht ein anderer Typ von Anfrage: Nicht einzelne Bücher oder Kurse stehen im Zentrum, sondern Muster und Kennzahlen des Gesamtbestands. Aggregatfunktionen beantworten daher eher Steuerungs- und Überblicksfragen als Detailfragen.

Einzeldaten vs. Aggregatwerte

Einzeldaten beantworten Detailfragen („Welches Buch kostet 12,90 €?“), Aggregatwerte beantworten Strukturfragen („Wie hoch ist der Durchschnittspreis aller Bücher?“).

SELECT COUNT(*) AS anzahl_buecher
FROM buch;

SELECT COUNT(DISTINCT verlag_id) AS anzahl_verlage
FROM buch;

SELECT SUM(bestand) AS gesamtbestand
FROM buch;

SELECT MIN(preis) AS guenstigstes_buch,
       MAX(preis) AS teuerstes_buch,
       AVG(preis) AS durchschnittspreis
FROM buch;
guenstigstes_buch teuerstes_buch durchschnittspreis
12.0029.5019.22

Aggregatfunktionen verdichten viele Buchzeilen zu kompakten Kennzahlen.

Auch wenn die Syntax knapp wirkt, verändert sich die Aussageebene deutlich: Das Ergebnis enthält keine vollständigen Datensätze, sondern berechnete Werte über viele Datensätze hinweg. Diese Verdichtung ist die fachliche Vorbereitung auf GROUP BY, bei dem Kennzahlen je Gruppe statt nur für die Gesamttabelle gebildet werden.

Fachlich wichtig: Ohne Gruppierung kann eine Anfrage nicht gleichzeitig frei gewählte Einzelattribute und Aggregatwerte ausgeben. Diese Einschränkung wird im nächsten Kapitel über GROUP BY systematisch aufgelöst.

Berechnete Spalten und SQL-Funktionen

SQL kann in SELECT auch berechnete Ergebnisspalten erzeugen. Solche Werte sind nicht zwingend als eigenes Attribut gespeichert, sondern entstehen erst beim Ausführen der Abfrage. Mit AS bekommen sie einen lesbaren Ausgabenamen.

SELECT Menge,
       Einzelpreis,
       Menge * Einzelpreis AS Positionswert
FROM BESTELLPOSITION;

In Aggregationen wird dieses Muster besonders wichtig, etwa bei SUM(Menge * Einzelpreis). COUNT(DISTINCT ...) hilft, wenn durch Joins dieselbe fachliche Einheit mehrfach auftaucht und nur eindeutig gezählt werden soll. Funktionen wie ROUND(...) für Rundung oder TIMESTAMPDIFF(...) als MariaDB/MySQL-Funktion für Zeitdifferenzen sind DBMS-abhängig und sollten gezielt dort eingesetzt werden, wo die Fragestellung solche Ergebniswerte verlangt.

JOIN
Tabellen verknüpfen mit JOIN
Zusammenhänge zwischen Tabellen auswerten

Das relationale Modell trennt Informationen auf mehrere Tabellen, um Redundanz zu vermeiden. Die Zusammenführung geschieht über Schlüsselbeziehungen. Genau hier wird der Übergang von Q2.1 (Modellierung) zu Q2.2 (Abfragesprache) besonders sichtbar.

Ohne JOIN würden wichtige Fachfragen unbeantwortet bleiben, weil relevante Attribute in unterschiedlichen Tabellen liegen. JOIN ist deshalb kein Zusatztrick, sondern die notwendige Brücke zwischen normalisierter Tabellenstruktur und auswertbarer Gesamtsicht.

Begriff: Join

Ein Join verknüpft Datensätze aus zwei oder mehr Tabellen. Die ON-Bedingung ist die Join-Bedingung: Sie legt fest, welche Datensätze fachlich zusammengehören, meist durch den Vergleich von Fremdschlüssel und passendem Primärschlüssel.

Einfacher INNER JOIN

SELECT b.titel, v.name AS verlag, v.ort
FROM buch AS b
INNER JOIN verlag AS v
        ON b.verlag_id = v.id;
titel verlag ort
Datenbanken BasiswissenLernwerk VerlagKassel
Informatik 1Campus MedienGöttingen
Robotik ProjekteZukunft VerlagHannover
SQL im UnterrichtNordlicht VerlagHamburg

Der Join ergänzt jeden Buchtitel um die Verlagsinformationen.

Tabellenqualifizierte Attributnamen (b.titel, v.name) sind zentral, sobald gleichnamige Spalten in mehreren Tabellen vorkommen.

Fachlich tragen dabei Primär- und Fremdschlüssel die Zuordnung: Der Primärschlüssel identifiziert einen Datensatz eindeutig, der Fremdschlüssel verweist auf diesen Datensatz in einer anderen Tabelle. Die Join-Bedingung in ON bildet genau diese definierte Beziehung ab, ohne die Modellierung aus Q2.1 erneut aufzubauen.

Mehrere Joins mit Aliasen

SELECT b.titel,
       a.name AS autor,
       v.name AS verlag
FROM buch AS b
INNER JOIN schreibt AS s ON s.buch_id = b.id
INNER JOIN autor AS a ON a.id = s.autor_id
INNER JOIN verlag AS v ON v.id = b.verlag_id
ORDER BY a.name, b.titel;
titel autor verlag
Algorithmik verstehenAyşe MertensLernwerk Verlag
Informatik 1Jonas RichterCampus Medien
SQL im UnterrichtJonas RichterNordlicht Verlag
Robotik ProjekteMara KönigZukunft Verlag

Über die Beziehungstabelle schreibt werden Buch, Autor und Verlag zusammengeführt.

Fachlicher Anschluss an Q2.1

Die Tabelle schreibt repräsentiert die n:m-Beziehung zwischen buch und autor. Ohne diese Beziehungstabelle wäre die Abfrage „Welcher Autor schrieb welchen Titel?“ nicht konsistent modellierbar.

Komplexere Modellpfade

In komplexeren relationalen Modellen liegt eine fachliche Eigenschaft nicht immer direkt in einer Tabelle. Rollen können über eine Zwischentabelle modelliert sein, Teammitgliedschaften können Zusatzattribute besitzen und Spezialisierungen werden über denselben Schlüssel an eine gemeinsame Basistabelle angeschlossen.

In der Projektmesse steht eine Rolle nicht als einzelnes Attribut in PERSON. Sie entsteht über PERSON_ROLLE und ROLLE. Ebenso werden SCHUELER und LEHRKRAFT als Spezialisierungen von PERSON über PersonID angeschlossen. SQL-Abfragen müssen deshalb den Modellpfad bewusst nachvollziehen, statt nur zwei Tabellen zu verbinden.

LEFT JOIN
INNER JOIN, LEFT JOIN und optionale Beziehungen
Fehlende Zuordnungen und optionale Datensätze sichtbar machen

Ein INNER JOIN liefert nur Datensätze, zu denen auf beiden Seiten eine passende Zuordnung existiert. Das ist richtig, wenn nur tatsächlich verbundene Fachobjekte gefragt sind. Ein LEFT JOIN erhält dagegen alle Datensätze der linken Tabelle und ergänzt passende Datensätze der rechten Tabelle, falls sie vorhanden sind.

Dadurch wird LEFT JOIN wichtig für optionale Beziehungen: Räume ohne Präsentation, Geräte ohne Prüfung, Wartungen ohne Lieferant oder Projekte ohne Bewertung dürfen dann nicht aus dem Ergebnis verschwinden.

SELECT r.RaumNr, p.PraesentationID
FROM RAUM r
LEFT JOIN PRAESENTATION p ON p.RaumID = r.RaumID;

Nach einem LEFT JOIN können fehlende Zuordnungen mit IS NULL sichtbar gemacht werden. In diesem Beispiel bleiben alle Räume erhalten; Räume ohne Präsentation haben rechts keinen passenden Datensatz.

SELECT r.RaumNr
FROM RAUM r
LEFT JOIN PRAESENTATION p ON p.RaumID = r.RaumID
WHERE p.PraesentationID IS NULL;
Bedingungen bei LEFT JOIN

Bedingungen auf rechte Tabellen können einen LEFT JOIN ungewollt wie einen INNER JOIN wirken lassen, wenn sie nachträglich in WHERE stehen. Soll die linke Seite auch bei fehlender rechter Zuordnung erhalten bleiben, gehören solche Einschränkungen oft direkt in die ON-Bedingung.

GROUP BY
Datensätze gruppieren
GROUP BY und HAVING

GROUP BY bündelt Datensätze nach einem oder mehreren Attributen; Aggregatfunktionen werden anschließend je Gruppe berechnet.

Damit entsteht eine neue Sicht auf Daten: Statt Einzelzeilen zu betrachten, werden Teilmengen mit gemeinsamer Eigenschaft (z. B. pro Verlag oder pro Kurs) als analytische Einheiten ausgewertet.

SELECT v.name AS verlag,
       COUNT(*) AS titelanzahl,
       AVG(b.preis) AS durchschnittspreis
FROM buch AS b
INNER JOIN verlag AS v ON v.id = b.verlag_id
GROUP BY v.name;
verlag titelanzahl durchschnittspreis
Lernwerk Verlag221.35
Campus Medien214.90
Zukunft Verlag129.50

Jede Verlagsgruppe erhält ihre eigene Kennzahlzeile.

WHERE und HAVING unterscheiden

WHERE filtert Zeilen vor der Gruppierung. HAVING filtert Gruppen nach der Aggregation.

SELECT v.name AS verlag,
       COUNT(*) AS titelanzahl
FROM buch AS b
INNER JOIN verlag AS v ON v.id = b.verlag_id
WHERE b.preis >= 15
GROUP BY v.name
HAVING COUNT(*) >= 2
ORDER BY titelanzahl DESC;
verlag titelanzahl
Lernwerk Verlag2
Nordlicht Verlag2

Nur Verlage mit mindestens zwei Titeln ab 15 € bleiben nach HAVING erhalten.

Vergleich: WHERE und HAVING

WHERE entscheidet, welche Zeilen in die Gruppierung eingehen. HAVING entscheidet, welche bereits gebildeten Gruppen im Ergebnis bleiben. Beide Klauseln ergänzen sich, ersetzen sich aber nicht.

Typischer Fehler

In einer gruppierten Anfrage dürfen im SELECT-Teil nur Gruppierungsattribute oder Aggregatwerte stehen. Einzelattribute ohne Gruppierung erzeugen fachlich uneindeutige Ergebnisse.

Transferfälle: fachliche Grenzwerte und Zählstrategie

In den Transferdatenbanken wird HAVING nicht nur für einfache Mindestanzahlen genutzt, sondern für fachliche Grenzwerte: Bestand gegen Bedarf, Durchschnittspunkte über einem Schwellwert, Anzahl je Status oder verfügbare Geräte je Typ. Die Grundregel bleibt gleich: WHERE filtert Zeilen vor der Gruppierung, HAVING filtert Gruppen nach der Aggregation.

Bei LEFT JOIN ist die Zählstrategie entscheidend. COUNT(*) zählt auch die erhaltene linke Zeile. COUNT(rechteTabelle.ID) zählt dagegen nur vorhandene Zuordnungen auf der rechten Seite. So lässt sich fachlich zwischen „Einheit bleibt sichtbar“ und „tatsächlich vorhandene Zuordnung wird gezählt“ unterscheiden.

Feste und dynamische Vergleichswerte

Ein fester Grenzwert prüft Gruppen gegen eine vorgegebene Schwelle, etwa HAVING AVG(...) > 10. Ein dynamischer Vergleichswert wird erst durch eine Unterabfrage aus dem Datenbestand berechnet, etwa HAVING AVG(...) > (SELECT AVG(...)).

Dadurch wird die Abfrage stärker vom konkreten Datenmodell abhängig und weniger schematisch: Bewertungssysteme, Material- und Ressourcenabgleiche oder Bedarfsvergleiche müssen aus den vorhandenen Beziehungen und Aggregationsebenen rekonstruiert werden.

Überblick SQL-Klauseln
Überblick: SQL-Klauseln in der Verarbeitungsperspektive
Prozesslogik von FROM bis LIMIT

Überblick: SQL-Klauseln in der Verarbeitungsperspektive

Für die Analyse hilft diese Reihenfolge der Verarbeitung: vom Festlegen der Datenbasis bis zur finalen Ausgabe.

  1. Tabellen als Datenquelle bestimmen FROM
  2. Tabellen über Schlüssel verknüpfen JOIN ... ON
  3. Datensätze vor der Gruppierung filtern WHERE
  4. Datensätze zu Gruppen zusammenfassen GROUP BY
  5. Gruppen nach Aggregation filtern HAVING
  6. Ergebnisspalten für die Ausgabe festlegen SELECT
  7. Ergebnisdarstellung sortieren ORDER BY
  8. Ausgabe auf einen Ausschnitt begrenzen LIMIT
Unterabfragen
Unterabfragen formulieren
Geschachtelte SELECT-Anweisungen

Unterabfragen (Subqueries) zerlegen komplexe Fragestellungen in Teilfragen. Die innere Anfrage liefert Werte, die von der äußeren Anfrage weiterverwendet werden.

Unterabfragen sind besonders dann sinnvoll, wenn ein Zwischenergebnis zuerst berechnet werden muss, bevor die eigentliche Filterung möglich ist, etwa bei Vergleichen mit Mittelwerten oder dynamisch bestimmten Wertelisten.

Fall A: Unterabfrage liefert genau einen Wert

SELECT titel, preis
FROM buch
WHERE preis > (
  SELECT AVG(preis)
  FROM buch
);
titel preis
Robotik Projekte29.50
Datenbanken Basiswissen24.90
SQL im Unterricht19.90

Die äußere Abfrage übernimmt den berechneten Durchschnittspreis als Vergleichswert.

Dieser Typ eignet sich für Vergleichsoperatoren wie > oder =, da die äußere Bedingung genau einen Referenzwert benötigt.

Fall B: Unterabfrage liefert mehrere Werte

SELECT titel, verlag_id
FROM buch
WHERE verlag_id IN (
  SELECT id
  FROM verlag
  WHERE ort = 'Kassel'
);
titel verlag_id
Datenbanken Basiswissen1
Algorithmik verstehen1
SQL Trainer8

IN prüft, ob der Verlag eines Buchs zur Kassel-Wertemenge gehört.

Liefert die innere Anfrage mehrere Werte, wird typischerweise IN verwendet. So kann die äußere Anfrage prüfen, ob ein Attribut zu einer ganzen Wertemenge gehört.

Fall C: EXISTS prüft, ob ein Zusammenhang existiert

EXISTS fragt nicht nach einem konkreten Ausgabewert, sondern danach, ob die innere Abfrage mindestens eine passende Zeile findet. Das passt zu Fragen wie „gibt es mindestens ein Exemplar zu diesem Buch?“ oder „gibt es mindestens eine passende Buchung?“.

SELECT b.Titel
FROM BUCH b
WHERE EXISTS (
  SELECT 1
  FROM EXEMPLAR e
  WHERE e.BuchID = b.BuchID
);

Fall D: NOT EXISTS findet fehlende Zuordnungen

NOT EXISTS behält genau die äußeren Datensätze, zu denen die innere Abfrage keine passende Zeile findet. Dieses Muster eignet sich für fehlende Zuordnungen: Bücher ohne offene Ausleihe, Geräte ohne Prüfung, Materialien ohne Buchung oder Projekte ohne Bewertung.

SELECT m.MaterialID, m.Bezeichnung
FROM MATERIAL m
WHERE NOT EXISTS (
  SELECT 1
  FROM MATERIALBUCHUNG mb
  WHERE mb.MaterialID = m.MaterialID
);
Korrelierte Unterabfrage

Eine Unterabfrage ist korreliert, wenn sie sich auf die aktuelle Zeile der äußeren Abfrage bezieht. Im Beispiel entsteht dieser Bezug durch mb.MaterialID = m.MaterialID. Die innere Abfrage wird damit nicht isoliert gelesen, sondern jeweils aus Sicht eines äußeren Materials.

Vollständigkeit mit doppelter Negation

Manche Fragen lauten nicht: „Gibt es eine passende Zuordnung?“, sondern: „Fehlt zu keinem geforderten Element eine Zuordnung?“ Solche Vollständigkeitsfragen können mit verschachteltem NOT EXISTS modelliert werden.

SELECT b.BewertungID
FROM BEWERTUNG b
WHERE NOT EXISTS (
  SELECT 1
  FROM KRITERIUM k
  WHERE NOT EXISTS (
    SELECT 1
    FROM BEWERTUNGSPUNKT bp
    WHERE bp.BewertungID = b.BewertungID
      AND bp.KriteriumID = k.KriteriumID
  )
);

Die äußere NOT EXISTS-Prüfung sagt: Es gibt kein Kriterium, zu dem der passende Bewertungspunkt fehlt. Das ist ein vertiefendes Kombinationsmuster, weil die Negation an eine vollständige fachliche Abdeckung gebunden wird.

LK-Vertiefung: Unterabfrage in HAVING

Auf erhöhtem Niveau können Unterabfragen auch in HAVING stehen, wenn Gruppen mit einem dynamisch berechneten Vergleichswert geprüft werden. Typisch sind Fragen wie: Welche Teams liegen über der durchschnittlichen Teamgröße? Welche Materialbedarfe überschreiten den durchschnittlichen Bedarf vergleichbarer Projekte?

SELECT pp.ProjektID,
       COUNT(*) AS Teamgroesse
FROM PROJEKT_PERSON pp
GROUP BY pp.ProjektID
HAVING COUNT(*) > (
  SELECT AVG(Teamgroesse)
  FROM (
    SELECT COUNT(*) AS Teamgroesse
    FROM PROJEKT_PERSON
    GROUP BY ProjektID
  ) AS teamzahlen
);
Regel für einfache Unterabfragen in WHERE

Bei Vergleichsoperatoren (=, <, > ...) muss die Unterabfrage genau einen Wert liefern. Bei mehreren Werten wird typischerweise IN benötigt.

Warnung vor unpassenden Unterabfragen

Unterabfragen sollen die Abfrage logisch klären, nicht verschleiern. Wenn dieselbe Aussage mit einem klaren Join einfacher lesbar ist, ist der Join meist didaktisch und technisch vorzuziehen.

Self-Join
Self-Join bei rekursiven Beziehungen
Dieselbe Tabelle in mehreren fachlichen Rollen verwenden

Eine rekursive Beziehung liegt vor, wenn Datensätze derselben Tabelle zueinander in Beziehung stehen. In SQL wird dafür keine neue Projekttabelle erfunden. Stattdessen wird dieselbe Tabelle mehrfach eingebunden und jede Rolle erhält einen eigenen Aliasnamen.

Im Projektkontext kann ein Projekt beispielsweise von einem anderen Projekt abhängen. Die Beziehungstabelle PROJEKT_ABHAENGIGKEIT speichert dann das Projekt, das eine Voraussetzung hat, und das vorausgesetzte Projekt.

SELECT p.Titel AS Projekt,
       vp.Titel AS Voraussetzung,
       pa.Art
FROM PROJEKT_ABHAENGIGKEIT pa
JOIN PROJEKT p ON p.ProjektID = pa.ProjektID
JOIN PROJEKT vp ON vp.ProjektID = pa.VoraussetzungProjektID;

Die Aliasnamen p und vp sind hier nicht kosmetisch, sondern fachlich notwendig: Beide verweisen auf PROJEKT, aber in unterschiedlichen Rollen.

Ein Self-Join kann mit weiterer Filterung oder Unterabfragen kombiniert werden, etwa wenn eine Projektabhängigkeit zusätzlich an den Status des vorausgesetzten Projekts gebunden wird oder geprüft werden soll, ob zum vorausgesetzten Projekt Teammitglieder existieren.

Typische SQL-Sonderfälle im Übungswerkzeug
  • NULL wird mit IS NULL oder IS NOT NULL geprüft.
  • Aliasnamen mit AS sind meist für die Ausgabe gedacht und selten allein prüfentscheidend.
  • LEFT JOIN und Bedingungen auf rechte Tabellen müssen sorgfältig formuliert werden.
  • HAVING filtert Gruppen, WHERE filtert Zeilen.
  • NOT EXISTS eignet sich für fehlende Zuordnungen.
  • Self-Joins benötigen mehrere Aliasnamen derselben Tabelle.
  • Unterabfragen sollen Teilfragen klären, nicht einfache Joins unnötig verschleiern.
  • Das SQL-Werkzeug führt ausschließlich SELECT-Aufgaben aus.
Datenbearbeitung
Daten bearbeiten
INSERT, UPDATE und DELETE

Mit SQL werden Datenbestände nicht nur gelesen, sondern auch verändert. Deshalb ist jede Änderungsanfrage fachlich zu begründen und vor Ausführung zu prüfen.

Im Unterschied zu SELECT greifen Änderungsbefehle direkt in die Datenintegrität ein. Besonders UPDATE und DELETE benötigen daher präzise Bedingungen, damit nur die fachlich beabsichtigten Datensätze betroffen sind.

INSERT, UPDATE und DELETE werden hier nur konzeptionell eingeordnet. Das SQL-Werkzeug führt aus Sicherheits- und Auswertungsgründen ausschließlich lesende SELECT-Aufgaben aus. Im aktuellen Aufgabenpool gibt es keine ausführbaren DML-, DDL- oder DCL-Aufgaben.

INSERT

INSERT INTO verlag (id, name, ort)
VALUES (7, 'Nordlicht Verlag', 'Hamburg');

INSERT INTO buch (id, titel, preis, bestand, verlag_id)
VALUES (101, 'SQL im Unterricht', 19.90, 12, 7);
id titel preis bestand verlag_id
101SQL im Unterricht19.90127

Nach INSERT ist der neue Titel mit Verlagsbezug in der Tabelle buch vorhanden.

UPDATE

UPDATE buch
SET preis = 18.90,
    bestand = bestand + 5
WHERE id = 101;
id titel preis bestand
101SQL im Unterricht18.9017

UPDATE passt den Preis an und erhöht gleichzeitig den Bestand des gewählten Datensatzes.

DELETE

DELETE FROM buch
WHERE id = 101;
id titel preis bestand
0 Zeilen (Datensatz mit id = 101 wurde entfernt)

DELETE entfernt den betroffenen Buchdatensatz vollständig aus der Tabelle.

Sicherheitsregel für UPDATE und DELETE

Fehlt die WHERE-Klausel, betrifft die Anweisung alle Datensätze einer Tabelle. In Unterricht und Praxis sollte daher vor jeder Änderung zunächst eine kontrollierende SELECT-Abfrage mit derselben Bedingung ausgeführt werden.

Bewährtes Vorgehen bei Datenänderungen

Erst Zielmenge mit SELECT prüfen, dann UPDATE oder DELETE mit identischer WHERE-Bedingung ausführen und abschließend das Ergebnis kontrollieren. So bleibt die Datenbearbeitung nachvollziehbar und konsistent.