Einführung in SQL: DML (1) - Daten abfragen
Aus Wikibooks
Eine Datenbank enthält eine Vielzahl von verschiedenen Daten. Abfragen dienen dazu, bestimmte Daten aus der Datenbank auszugeben. Dabei kann die Ergebnismenge entsprechend den Anforderungen eingegrenzt und genauer gesteuert werden.
Dieser Teilbereich der Data Manipulation Language (DML) behandelt den SQL-Befehl SELECT, mit dem Abfragen durchgeführt werden.
Dieses Kapitel behandelt einfache Abfragen. Ausführlicher wird der SELECT-Befehl unter Abfragen für Fortgeschrittene behandelt, beginnend mit Ausführliche SELECT-Struktur; unter Ausblick auf komplexe Abfragen gibt es Hinweise auf diese weiteren Möglichkeiten.
Inhaltsverzeichnis |
[Bearbeiten] SELECT – Allgemeine Hinweise
SELECT ist in der Regel der erste und wichtigste Befehl, den der SQL-Neuling kennenlernt, und das aus gutem Grund. Man kann damit keinen Schaden anrichten. Ein Programmierfehler führt höchstens zu einer Fehlermeldung oder dem Ausbleiben des Abfrageergebnisses, aber nicht zu Schäden am Datenbestand. Trotzdem erlaubt der Befehl das Herantasten an die wichtigsten Konzepte von DML, und die anderen Befehle müssen nicht mehr so intensiv erläutert werden.
Dieser Befehl enthält die folgenden Bestandteile ("Klauseln" genannt).
SELECT [DISTINCT | ALL]
<spaltenliste> | *
FROM <tabellenliste>
[WHERE <bedingungsliste>]
[GROUP BY <spaltenliste> ]
[HAVING <bedingungsliste>]
[UNION <select-ausdruck>]
[ORDER BY <spaltenliste> ]
;
Die Reihenfolge der Klauseln ist fest im SQL-Standard vorgegeben. Klauseln, die in [] stehen, sind nicht nötig, sondern können entfallen; der Name des Befehls und die FROM-Angaben sind unbedingt erforderlich, das Semikolon als Standard empfohlen.
Die wichtigsten Teile werden in den folgenden Abschnitten erläutert.
Die folgenden Punkte verlangen vertiefte Beschäftigung mit SQL:
- GROUP BY – Daten gruppieren
- HAVING – weitere Einschränkungen
- UNION – mehrere Abfragen verbinden
Diese Punkte sowie weitere Einzelheiten zu den wichtigsten Bestandteilen werden in Ausführliche SELECT-Struktur und anderen "fortgeschrittenen" Kapiteln behandelt.
Die Beispiele beziehen sich auf den Anfangsbestand der Beispieldatenbank; auf die Ausgabe der selektierten Datensätze verzichte ich. Bitte probieren Sie alle Beispiele aus und nehmen Sie verschiedene Änderungen vor, um die Auswirkungen zu erkennen.
[Bearbeiten] Die einfachste Abfrage
Gesucht wird der Inhalt der Tabelle der Fahrzeughersteller mit all ihren Spalten und Datensätzen (Zeilen).
Schauen wir uns das Beispiel etwas genauer an:
- Die beiden Begriffe SELECT und FROM sind SQL-spezifische Bezeichner.
- Fahrzeughersteller ist der Name der Tabelle, aus der die Daten selektiert und ausgegeben werden sollen.
- Das Sternchen, Asterisk genannt, ist eine Kurzfassung für "alle Spalten".
[Bearbeiten] Eingrenzen der Spalten
Nun wollen wir nur bestimmte Spalten ausgeben, nämlich eine Liste aller Fahrzeughersteller; das Land interessiert uns dabei nicht. Dazu müssen zwischen den SQL-Bezeichnern SELECT und FROM die auszugebenden Spalten angegeben werden. Sind es mehrere, dann werden diese durch jeweils ein Komma getrennt.
Die Namensliste aller Fahrzeughersteller wird durch folgenden SQL-Befehl erreicht:
Folgendes Beispiel gibt die beiden Spalten für Name und Land des Herstellers aus. Die Spalten werden durch Komma getrennt.
Für die Ausgabe kann eine (abweichende) Spaltenüberschrift festgelegt werden. Diese wird als Spalten-Alias bezeichnet. Die Überschrift wird durch das Wörtchen AS vom Spaltennamen getrennt, dieses kann auch entfallen. Das vorherige Beispiel sieht also folgendermaßen aus:
[Bearbeiten] DISTINCT – Keine doppelten Zeilen
Gesucht wird die Liste der Herstellerländer:
Dabei stellen wir fest, dass je Hersteller eine Zeile ausgegeben wird. Somit erscheint beispielweise 'Deutschland' mehrmals. Damit keine doppelten Zeilen ausgegeben werden, wird DISTINCT vor den Spaltennamen in das SQL-Statement eingefügt:
Somit erscheint jedes Herstellerland nur einmal in der Liste.
Die Alternative zu DISTINCT ist übrigens das in der Syntax genannte ALL: alle Zeilen werden gewünscht, ggf. auch doppelte. Dies ist aber der Standardwert, ALL kann weggelassen werden.
Vertiefte Erläuterungen sind unter Nützliche Erweiterungen zu finden.
[Bearbeiten] WHERE – Eingrenzen der Ergebnismenge
Fast immer soll nicht der komplette Inhalt einer Tabelle ausgegeben werden. Dazu wird die Ergebnismenge mittels Bedingungen in der WHERE-Klausel eingegrenzt, welche nach dem Tabellennamen im SELECT-Befehl steht.
Eine Bedingung ist ein logischer Ausdruck, dessen Ergebnis WAHR oder FALSCH ist. In diesen logischen Ausdrücken werden die Inhalte der Spalten (vorwiegend) mit konstanten Werten verglichen. Hierbei stehen verschiedene Operatoren zur Verfügung, vor allem:
= gleich <> ungleich; seltener auch: != < kleiner als <= kleiner als oder gleich > größer als >= größer als oder gleich
Bedingungen können durch die logischen Operatoren OR und AND und die Klammern () verknüpft werden. Je komplizierter solche Verknüpfungen werden, desto sicherer ist es, die Bedingungen durch Klammern zu gliedern. Mit diesen Mitteln lässt sich die Abfrage entsprechend eingrenzen.
Beispielsweise sollen alle Hersteller angezeigt werden, die ihren Sitz in Schweden oder Frankreich haben:
(Auf die Klammern kann hier verzichtet werden.)
SQL-Quelltext:
SELECT * FROM Fahrzeughersteller WHERE ( Land = 'Schweden' ) OR ( Land = 'Frankreich' );
Hinter der WHERE-Klausel kann man also eine oder mehrere (mit einem booleschen Operator verknüpft) Bedingungen einfügen. Jede einzelne besteht aus dem Namen der Spalte, deren Inhalt überprüft werden soll, und einem Wert, wobei beide mit einem Vergleichsoperator verknüpft sind.
In einer anderen Abfrage sollen alle Fahrzeughersteller angezeigt werden, die außerhalb Deutschlands sitzen. Jetzt könnte man alle anderen Fälle einzeln in der WHERE-Klausel auflisten, oder man dreht einfach den Vergleichsoperator um.
Das Gleichheitszeichen aus der oberen Abfrage wurde durch das Ungleichheitszeichen ersetzt. Dadurch werden jetzt alle Hersteller ausgegeben, deren Sitz ungleich Deutschland ist.
Vertiefte Erläuterungen sind unter WHERE-Klausel im Detail zu finden.
[Bearbeiten] ORDER BY – Sortieren
Nachdem wir nun die Zeilen und Spalten der Ergebnismenge eingrenzen können, wollen wir die Ausgabe der Zeilen sortieren. Hierfür wird die ORDER BY-Klausel genutzt. Diese ist die letzte im SQL-Befehl vor dem abschließenden Semikolon und enthält die Spalten, nach denen sortiert werden soll.
So lassen wir uns die Liste der Hersteller nach dem Namen sortiert ausgeben:
Anstatt des Spaltennamens kann auch die Nummer der Spalte genutzt werden. Mit dem folgenden Statement erreichen wir also das gleiche Ergebnis, da Name die 2. Spalte in unserer Ausgabe ist:
Die Sortierung erfolgt standardmäßig aufsteigend; das kann auch durch ASC ausdrücklich angegeben werden. Die Sortierreihenfolge kann mit dem DESC-Bezeichner in absteigend verändert werden.
In SQL kann nicht nur nach einer Spalte sortiert werden. Es können mehrere Spalten zur Sortierung herangezogen werden. Hierbei kann jede Spalte aufsteigend oder absteigend sortiert werden. Nach den Spalten, die weiter links in der ORDER BY-Klausel stehen, wird zuerst sortiert.
Der folgende Befehl liefert die Hersteller – zuerst absteigend nach Land und dann aufsteigend sortiert nach dem Namen – zurück.
[Bearbeiten] FROM – Mehrere Tabellen verknüpfen
In fast allen Abfragen werden Informationen aus mehreren Tabellen zusammengefasst. Die sinnvolle Speicherung von Daten in getrennten Tabellen ist eines der Merkmale eines relationalen DBMS; deshalb müssen die Daten bei einer Abfrage nach praktischen Gesichtspunkten zusammengeführt werden.
[Bearbeiten] Traditionell mit FROM und WHERE
Beim "traditonellen" Weg werden dazu einfach alle Tabellen in der FROM-Klausel aufgeführt und durch jeweils eine Bedingung in der WHERE-Klausel verknüpft.
Ermittle die Angaben der Mitarbeiter, deren Abteilung ihren Sitz in Dortmund oder Bochum hat.
SELECT mi.Name, mi.Vorname, mi.Raum, ab.Ort FROM Mitarbeiter mi, Abteilung ab WHERE mi.Abteilung_ID = ab.ID AND ab.Ort IN ('Dortmund', 'Bochum') ORDER BY mi.Name, mi.Vorname;
Es werden also Informationen aus den Tabellen Mitarbeiter (Name und Raum) sowie Abteilung (Ort) gesucht. Für die Verknüpfung der Tabellen werden folgende Bestandteile benötigt:
- In der FROM-Klausel stehen die benötigten Tabellen.
- Zur Vereinfachung wird jeder Tabelle ein Kürzel als Tabellen-Alias zugewiesen.
- In der Spaltenliste wird jede einzelne Spalte mit dem Namen der betreffenden Tabelle bzw. dem Alias verbunden. (Der Tabellenname bzw. Alias kann sehr oft weggelassen werden; aber schon wegen der Übersichtlichkeit sollte er immer benutzt werden.)
- Die WHERE-Klausel enthält die Verknüpfungsbedingung "mi.Abteilung_ID = ab.ID" – zusätzlich zur Einschränkung nach dem Sitz der Abteilung.
Jede Tabelle in einer solchen Abfrage benötigt mindestens eine direkte Verknüpfung zu einer anderen Tabelle. Alle Tabellen müssen zumindest indirekt miteinander verknüpft sein. Falsche Verknüpfungen sind eine häufige Fehlerquelle.
Vertiefte Erläuterungen sind unter Einfache Tabellenverknüpfung zu finden.
[Bearbeiten] Modern mit JOIN...ON
Beim "modernen" Weg wird eine Tabelle in der FROM-Klausel aufgeführt, nämlich diejenige, die als wichtigste oder "Haupttabelle" der Abfrage angesehen wird. Eine weitere Tabelle wird durch JOIN und eine Bedingung in der ON-Klausel verknüpft.
Das obige Beispiel sieht dann so aus:
SELECT mi.Name, mi.Vorname, mi.Raum, ab.Ort FROM Mitarbeiter mi JOIN Abteilung ab ON mi.Abteilung_ID = ab.ID WHERE ab.Ort IN ('Dortmund', 'Bochum') ORDER BY mi.Name, mi.Vorname;
Für die Verknüpfung der Tabellen werden folgende Bestandteile benötigt:
- In der FROM-Klausel steht eine der benötigten Tabellen.
- In der JOIN-Klausel steht jeweils eine weitere Tabelle.
- Die ON-Klausel enthält die Verknüpfungsbedingung "mi.Abteilung_ID = ab.ID".
- Die WHERE-Klausel beschränkt sich auf die wirklich gewünschten Einschränkungen für die Ergebnismenge.
Ein Tabellen-Alias ist wiederum für alle Tabellen sinnvoll. In der Spaltenliste und auch zur Sortierung können alle Spalten aller Tabellen benutzt werden.
Vertiefte Erläuterungen sind unter Arbeiten mit JOIN zu finden.
[Bearbeiten] Ausblick auf komplexe Abfragen
Das folgende Beispiel ist erheblich umfangreicher und geht über "Anfängerbedürfnisse" deutlich hinaus. Es zeigt aber sehr schön, was alles mit SQL möglich ist:
Gesucht werden die Daten der Versicherungsnehmer im Jahr 2008, und zwar die Adresse, die Höhe des Gesamtschadens und die Anzahl der Schadensfälle.
SELECT vn.Name, vn.Vorname, vn.Strasse, vn.Hausnummer AS HNR, vn.PLZ, vn.Ort, sum(sf.Schadenshoehe) AS Gesamtschaden, count(sf.ID) AS Anzahl FROM Versicherungsnehmer vn JOIN Versicherungsvertrag vv ON vv.Versicherungsnehmer_ID = vn.ID JOIN Fahrzeug fz ON fz.ID = vv.Fahrzeug_ID JOIN Zuordnung_SF_FZ zu ON zu.Fahrzeug_ID = fz.ID JOIN Schadensfall sf ON sf.ID = zu.Schadensfall_ID WHERE EXTRACT(YEAR FROM sf.Datum) = 2008 GROUP BY vn.Name, vn.Vorname, vn.Strasse, vn.Hausnummer, vn.PLZ, vn.Ort ORDER BY Gesamtschaden, Anzahl;
NAME VORNAME STRASSE HNR PLZ ORT GESAMTSCHADEN ANZAHL Heckel Obsthandel GmbH Gahlener Str. 40 46282 Dorsten 1.438,75 1 Antonius Bernhard Coesfelder Str. 23 45892 Gelsenkirchen 1.983,00 1
Hierbei kommen die Funktionen SUM (Summe) und COUNT (Anzahl) zum Einsatz. Diese können nur eingesetzt werden, wenn die Datenmenge richtig gruppiert wurde. Deshalb wird mit GROUP BY das Datenmaterial nach allen verbliebenen zur Ausgabe vorgesehenen Datenfeldern gruppiert.
Vertiefte Erläuterungen sind zu finden unter Funktionen sowie Gruppierungen.
[Bearbeiten] Zusammenfassung
In diesem Kapitel lernten wir die Grundlagen eines SELECT-Befehls kennen:
- SELECT-Befehle werden zur Abfrage von Daten aus Datenbanken genutzt.
- Die auszugebenden Spalten können festgelegt werden, indem die Liste der Spalten zwischen den Bezeichnern SELECT und FROM angegeben wird.
- Mit DISTINCT werden identische Zeilen in der Ergebnismenge nur einmal ausgegeben.
- Die Ergebnismenge wird mittels der WHERE-Klausel eingegrenzt.
- Die WHERE-Klausel enthält logische Ausdrücke. Diese können mit AND und OR verknüpft werden.
- Mittels der ORDER BY-Klausel kann die Ergebnismenge sortiert werden.
Die Reihenfolge innerhalb eines SELECT-Befehls ist zu beachten. SELECT und FROM sind hierbei Pflicht, das abschließende Semikolon als Standard empfohlen. Alle anderen Klauseln sind optional.
[Bearbeiten] Übungen
Erstelle für die Beispieldatenbank folgende Abfragen. Nutze hierbei die Tabelle Abteilung.
Gib alle Informationen zu allen Abteilungen aus.
?
Gib alle Abteilungen aus, deren Standort 'Bochum' ist.
?
Gib alle Abteilungen aus, deren Standort 'Bochum' oder 'Essen' ist. Hierbei soll nur der Name der Abteilung ausgegeben werden.
?
Gib nur die Kurzbezeichnungen aller Abteilungen aus. Hierbei sollen die Abteilungen nach den Standorten sortiert werden.
?
Welche Bestandteile eines SELECT-Befehls sind unbedingt erforderlich und können nicht weggelassen werden?
?