Abfragen: Grundlagen

Über Datenbankabfragen können wir uns Tabellen anzeigen lassen. Dazu hat sich eine Sprache durchgesetzt, deren Befehle wie englische Sätze klingen: SQL, die Structured Query Language. Die folgende Fahrschuldatenbank soll als Beispiel dienen.

Die folgende Abfrage zeigt die vollständige Tabelle fahrlehrer an.

SELECT * FROM fahrlehrer

Manchmal interessiert man sich nur für bestimmte Spalten. Man sagt auch, dass man diese Spalten aus der ursprünglichen Tabelle „herausprojiziert“ und spricht folglich von einer Projektion. Bsp.:

„Die Vornamen und Nachnamen aller Fahrlehrer“

würde der folgenden Abfrage entsprechen.

SELECT vorname, nachname FROM fahrlehrer

Manchmal interessiert man sich nur für bestimmte Zeilen. Man sagt auch, dass man aus der ursprünglichen Tabelle „selektiert“ und spricht folglich von einer Selektion. Die Selektion erfolgt nach einer Bedingung, die man sehr flexibel wählen kann. Bsp.:

„Vornamen, Nachnamen und Fahrstunden aller Fahrschüler, die mehr als 15 Fahrstunden absolviert haben“

...würde der folgenden Abfrage entsprechen.

SELECT vorname, nachname, anz_fahrstunden
FROM   fahrschueler
WHERE  anz_fahrstunden > 15

Statt der Bedingung anz_fahrstunden > 15 sind viele weitere möglich; hier eine Auflistung einiger am häufigsten verwendeter.

Bedingung Bedeutung
vorname = "Manfred" Gleichheit für Zeichenketten
vorname <> "Manfred" Ungleichheit für Zeichenketten
anzahl_fahrstunden = 10 Gleichheit für Zahlen
anzahl_fahrstunden >= 10 Zahlenvergleich
theorie_bestanden = 1 Prüfung für Wahrheitswerte: 1 entspricht „wahr“, 0 entspricht „falsch”
gebdatum < '2000-04-01' Datumsvergleich
vorname LIKE 'A%' Musterabgleich für Zeichenketten: Nur Vornamen, die mit A beginnen. Das % dient als Platzhalter für eine beliebige Zeichenkette, auch wildcard genannt.
gebdatum IS NULL Der Wert in Spalte gebdatum ist leer gelassen worden
gebdatum IS NOT NULL Der Wert in Spalte gebdatum ist nicht leer gelassen worden

Bedingungen lassen sich zu neuen Bedingungen kombinieren.

<bedingung1> AND <bedingung2> Beide Bedingungen müssen erfüllt sein.
<bedingung1> OR <bedingung2> Mindestens eine der Bedingungen muss erfüllt sein.
NOT <bedingung> Die Bedingung darf nicht erfüllt sein.

Manchmal ist nicht klar, in welcher Reihenfolge die AND-, OR- und NOT-Operatoren gelesen werden sollen. In diesem Fall klammert man entsprechend, ganz analog zur Klammerung bei Zahlentermen. Siehe dazu auch das folgende Beispiel:

Bsp.: „Alle Fahrschüler, die 2001 geboren wurden, oder aber die Theorieprüfung bestanden haben.“

SELECT *
FROM   fahrschueler
WHERE  (geburtsdatum >= '2001-01-01' AND geburtsdatum <  '2002-01-01') OR
       theorie_bestanden = 1

Manchmal möchte man die Zeilen mehrerer Tabellen kombinieren. Die Idee ist, dass man eine Tabelle als eine Menge von Elementen auffasst und die Mengenoperationen Vereinigung, Schnitt, Mengendifferenz anwendet. Wichtig ist hierbei, dass das Schema der beteiligten Tabellen (also die Spaltennamen inkl. Datentypen) übereinstimmt. Bsp.:

„Alle Vornamen von Fahrlehrern und Fahrschülern“

...würde der folgenden Abfrage entsprechen.

SELECT vorname FROM fahrlehrer
UNION
SELECT vorname FROM fahrschueler

Die hierzu passende SQL-Abfrage liest sich wieder wie ein englischer Satz; genauer werden zwei Sätze mittels der Konjunktion UNION verbunden. Folgende weitere SQL-Operatoren gibt es:

SQL-Operator Mengenoperator Math. Symbol
UNION Vereinigung $\bigcup$
INTERSECT Schnitt $\bigcap$
EXCEPT Differenz $\setminus$

Jede Spalte ist mit einem Spaltenkopf ausgestattet, dem sogenannten Attribut. Der Spaltenkopf kann umbenannt werden. Die Umbenennung ist vor allem später wichtig, wenn es passieren kann, dass beim Verschmelzen zweier Tabellen mehrere Spaltenköpfe denselben Namen tragen. In folgendem Beispiel wird der Spaltenkopf „vorname“ in „name“ umbenannt.

SELECT vorname AS name
FROM   fahrlehrer

Die Zeilen einer Tabelle können sortiert werden mittels ORDER BY. Es können mehrere Spaltennamen angegeben werden, per Komma getrennt. Um eine absteigende Sortierung zu erzielen, muss das Schlüsselwort DESC (englisch descending) angefügt werden, z.B. ORDER BY anz_fahrstunden DESC.

SELECT   vorname, nachname, anz_fahrstunden
FROM     fahrschueler
ORDER BY anz_fahrstunden

Wir waren bisher nicht ganz korrekt: Eine Tabelle ist eigentlich eine Multimenge von Zeilen, nicht eine Menge. Der Unterschied ist, dass Elemente in einer Multimenge mehrfach vorkommen dürfen, in einer Menge hingegen nicht.

Tabellen können grundsätzlich Zeilen mehrfach enthalten. Wir können Duplikate entfernen, indem wir in der Anfrage SELECT DISTINCT statt bloß SELECT formulieren. „Distinct“ ist englisch für „unterschieden“1 .

Tabelle als Multimenge von Zeilen

Multimenge“ bedeutet, dass Elemente mehrfach enthalten sein dürfen.

Die folgende Abfrage selektiert also alle Vornamen unter den Fahrschülern.

SELECT   vorname
FROM     fahrschueler
ORDER BY vorname

Tabelle als Menge von Zeilen

Menge“ bedeutet, dass Elemente einfach enthalten sind (zugehörig vs. nicht zugehörig).

Die folgende Abfrage selektiert also alle verschiedenen Vornamen unter den Fahrschülern.

SELECT DISTINCT vorname
FROM            fahrschueler
ORDER BY        vorname

Manchmal interessiert man sich nur für eine bestimmte Anzahl an Ergebnissen, z.B. die „Top 3“, und will also die Zeilenanzahl limitieren (deutsch: begrenzen). In diesem Fall fügt man einer (beliebig komplexen) SELECT-Abfrage noch eine LIMIT-Klausel an. Diese bewirkt, dass abschließend nur die ersten n Zeilen ausgegeben werden.

SELECT   vorname, nachname, anz_fahrstunden
FROM     fahrschueler
ORDER BY anz_fahrstunden DESC
LIMIT    3
  1. Im Deutschen gibt es zudem auch noch das selten verwendete Wort „distinguiert“, das denselben Ursprung hat, aber anders verwendet wird.