Datenabfragen mit SQL
Der SELECT-Befehl
Die SQL-Abfrage erfolgt mit dem Befehl SELECT unter Angabe von bis zu sechs Komponenten. Die allgemeine Syntax hat die Gestalt:
SELECT [ALL | DISTINCT] {spalten | *}
FROM tabelle [alias] [tabelle [alias]] ...
[WHERE {bedingung | unterabfrage}]
[GROUP BY spalten [HAVING {bedingung | unterabfrage}]]
[ORDER BY spalten [ASC | DESC]...];
Die schwierige Syntax lässt sich wie folgt verstehen:
Klausel |
Erläuterung |
SELECT [DISTINCT] |
Wähle die Werte aus der/den Spalte [mehrfache Datensätze nur einmal] ... |
FROM |
... aus der Tabelle bzw. den Tabellen ... |
WHERE |
... wobei die Bedingung(en) erfüllt sein soll(en) ... |
GROUP BY |
... und gruppiere die Ausgabe von allen Zeilen mit gleichem Attributwert zu einer einzigen ... |
HAVING |
... wobei darin folgende zusätzliche Bedingung(en) gelten müssen/muss ... |
ORDER BY [ASC/DESC] |
... und sortiere nach den Spalten [auf- bzw. absteigend]. |
Auswahl von Zeilen - Selektion
Aus der Tabelle Schüler sollen alle Zeilen selektiert werden, in denen der Name "Müller" steht.
(Die Selektion hat also die Form SName = 'Müller'(Schüler))
Die Umsetzung in SQL lautet:
SELECT *
FROM Schüler
WHERE Name = 'Müller';
Schüler |
|
Ergebnis
|
SNr |
Vorname |
Name |
4711 |
Paul |
Müller |
0815 |
Erich |
Schmidt |
7472 |
Sven |
Lehmann |
1234 |
Olaf |
Müller |
2313 |
Jürgen |
Paulsen |
|
→
|
SNr |
Vorname |
Name |
4711 |
Paul |
Müller |
1234 |
Olaf |
Müller |
|
Die WHERE-Klausel liefert also die Selektion. Um zu zeigen, dass alle Spalten angezeigt werden sollen, wird das Stern-Symbol verwendet.
Nun sollen aus der Tabelle Schüler sollen alle Zeilen selektiert werden, in denen der Name "Müller" steht und deren Vorname mit "O" beginnt.
(Die Selektion hat also die Form SName = 'Müller' UND Vorname beginnt mit 'O'(Schüler))
Die Umsetzung in SQL lautet:
SELECT *
FROM Schüler
WHERE Name = 'Müller' AND Vorname LIKE 'O%';
Schüler |
|
Ergebnis
|
SNr |
Vorname |
Name |
4711 |
Paul |
Müller |
0815 |
Erich |
Schmidt |
7472 |
Sven |
Lehmann |
1234 |
Olaf |
Müller |
2313 |
Jürgen |
Paulsen |
|
→
|
SNr |
Vorname |
Name |
1234 |
Olaf |
Müller |
|
Bedingungen lassen sich mit AND, OR und NOT verknüpfen. Das Prozentsymbol steht als Platzhalter für eine beliebige Folge von Zeichen. Soll ein einzelnes Zeichen ausgeblendet werden, so benutzt man den Unterstrich als Joker. LIKE wird verwendet im Sinne von "SO WIE".
Operator |
Erklärung |
= < <= >= > <> |
vergleicht ein Attributwert mit einem anderen bzw. Konstante auf Gleichheit, kleiner als, kleiner gleich, größer gleich, größer, Ungleichheit |
BETWEEN ... AND ... |
vergleicht, ob der Attributwert zwischen zwei Grenzen liegt (incl. Grenzwerte) |
IN (..., ..., ...) |
vergleicht, ob der Attributwert ein Element der Menge ist |
LIKE |
vergleicht Zeichenketten anhand von Ähnlichkeitsoperatoren mit Unterscheidung auf Groß- und Kleinschreibung: %: Platzhalter für beliebige Zeichen _: Platzhalter für genau ein Zeichen |
IS (NOT) NULL |
prüft, ob ein Attributwert (nicht) undefiniert ist |
Auswahl von Spalten - Projektion
Aus der Tabelle Schüler sollen alle Spalten mit dem Attribut "Name" projiziert werden.
(Die Projektion hat also die Form PName(Schüler))
Die Umsetzung in SQL lautet:
SELECT Name
FROM Schüler;
Schüler |
|
Ergebnis |
SNr |
Vorname |
Name |
4711 |
Paul |
Müller |
0815 |
Erich |
Schmidt |
7472 |
Sven |
Lehmann |
1234 |
Olaf |
Müller |
2313 |
Jürgen |
Paulsen |
|
→
|
Name |
Müller |
Schmidt |
Lehmann |
|
Paulsen |
|
Um Mehrfacheintragungen zu unterbinden, muss dem SELECT-Befehl das Schlüsselwort DISTINCT hinzugefügt werden.
Die Umsetzung in SQL lautet:
SELECT DISTINCT Name
FROM Schüler;
Schüler |
|
Ergebnis |
SNr |
Vorname |
Name |
4711 |
Paul |
Müller |
0815 |
Erich |
Schmidt |
7472 |
Sven |
Lehmann |
1234 |
Olaf |
Müller |
2313 |
Jürgen |
Paulsen |
|
→
|
Name |
Müller |
Schmidt |
Lehmann |
Paulsen |
|
Hintereinanderausführung von Projektion und Selektion
Aus der Tabelle Schüler sollen die Vornamen aller Schüler angezeigt werden, deren Nachname Müller ist.
(Die Abfrage hat also die Form PVorname(SName = 'Müller'(Schüler)))
Die Umsetzung in SQL lautet:
SELECT Vorname
FROM Schüler
WHERE Name = 'Müller';
Schüler |
|
Ergebnis |
SNr |
Vorname |
Name |
4711 |
Paul |
Müller |
0815 |
Erich |
Schmidt |
7472 |
Sven |
Lehmann |
1234 |
Olaf |
Müller |
2313 |
Jürgen |
Paulsen |
|
→
|
|
Die Abarbeitung des SQL-Befehls erfolgt also immer von innen nach außen, d. h. zuerst die Selektion, dann die Projektion.
Inner Join in SQL
Aus den Tabellen Schüler und Kurse soll eine Tabelle gebildet werden. Das verbindende Attribut lautet SNr.
(Die Abfrage hat also die Form JSchüler.SNr = Kurs.SNr(Schüler, Kurse))
Die Umsetzung in SQL lautet:
SELECT *
FROM Schüler INNER JOIN Kurse
ON Schüler.SNr = Kurse.SNr;
Schüler |
Kurse |
|
Ergebnis |
SNr |
Vorname |
Name |
4711 |
Paul |
Müller |
0815 |
Erich |
Schmidt |
7472 |
Sven |
Lehmann |
1234 |
Olaf |
Müller |
2313 |
Jürgen |
Paulsen |
|
SNr |
KNr |
Fehlzeit |
Punkte |
0815 |
03 |
0 |
12 |
4711 |
03 |
12 |
03 |
4711 |
09 |
8 |
05 |
1234 |
23 |
3 |
14 |
|
→
|
SNr |
Vorname |
Name |
SNr |
KNr |
Fehlzeit |
Punkte |
4711 |
Paul |
Müller |
4711 |
03 |
12 |
03 |
4711 |
Paul |
Müller |
4711 |
09 |
8 |
05 |
0815 |
Erich |
Schmidt |
0815 |
03 |
0 |
12 |
1234 |
Olaf |
Müller |
1234 |
23 |
3 |
14 |
|
Das Ergebnis ist ein INNER JOIN, wobei die entstandene Tabelle Spalten mehrfach enthält. Ein solcher Ergebnis wird aber i. d. R. nicht gewünscht. Es genügen oft nur einige Spalten des Verbundes.
Aus den Tabellen Schüler und Kurse sollen alle Schülernamen mit ihren Fehlzeiten aufgelistet werden. Der Befehl lautet:
SELECT Schüler.Vorname, Schüler.Name, Kurse.KNr, Kurse.Fehlzeit
FROM Schüler INNER JOIN Kurse
ON Schüler.SNr = Kurse.SNr
ORDER BY Kurse.Fehlzeit DESC;
Ergebnis |
Vorname |
Name |
KNr |
Fehlzeit |
Paul |
Müller |
03 |
12 |
Olaf |
Müller |
23 |
3 |
Erich |
Schmidt |
03 |
0 |
Erich |
Schmidt |
23 |
0 |
|