Datenbank/SQL-Grundlagen
Dieses Kapitel ist eine kurze Einführung in die Syntax von SQL (Structured Query Language) zur Bearbeitung von relationalen Datenbanken. Es ist an kein konkretes Datenbankmanagementsystem gebunden. Die meisten Abfragen funktionieren in allen Datenbankmanagementsystemem (DBMS) gleich oder zumindest ähnlich. Erst bei den unterstützten Datentypen (SQLite kennt beispielsweise nur vier, was für die meisten Anwendungsfälle ausreicht, MySQL hingegen Dutzende) und eingebauten Funktionen wie Volltextsuche oder Datumsformatierung wird es dann meist speziell. Dort sollten Sie im Zweifelsfall das Handbuch des entsprechenden Systems konsultieren.
Die Bezeichnung SQL bezieht sich auf das englische Wort query (englisch für Abfrage). Mit Abfragen werden die in einer Datenbank gespeicherten Daten abgerufen oder verändert und dem Benutzer oder einer Anwendersoftware zur Verfügung gestellt.
Das Ergebnis einer Abfrage sieht wiederum aus wie eine Tabelle und kann oft auch wie eine Tabelle angezeigt, bearbeitet und weiterverwendet werden.
Dieser Artiken möchte die grundlegenden Befehle und Begriffe erklären.
Inhaltsverzeichnis
- 1 Vorbereitung
- 2 Abfragen
- 2.1 Einfaches Lesen einer Tabelle mit SELECT und FROM
- 2.2 Abfrage mit Spaltenauswahl
- 2.3 AS - Abfrage mit Umbenennung
- 2.4 WHERE - Abfrage mit Filter
- 2.5 LIKE - Abfrage mit Filter nach Inhalt
- 2.6 ORDER BY - Abfrage mit Filter und Sortierung
- 2.7 Abfrage mit verknüpften Tabellen
- 2.8 Aliasnamen für Tabellen
- 2.9 COUNT & Co - Aggregat-Funktionen
- 2.10 GROUP BY - Bilden von Teilmengen
- 2.11 DISTINCT - Abfrage mit eindeutigen Werten
- 2.12 HAVING - Filtern von aggregierten Werten
- 2.13 Mengenoperatoren: UNION, EXCEPT und INTERSECT
- 2.14 Zusammenfassung
- 3 Datensätze hinzufügen und ändern
- 4 Tabellen erzeugen
- 5 Quellen
- 6 Siehe auch
Vorbereitung
Wenn Sie bereits über ein installiertes DBMS verfügen, können Sie den ersten Unterabschnitt überspringen.
Einrichten eines DBMS
Um die hier gezeigten Abfragen ausführen zu können, benötigen Sie ein DBMS (Datenbankmanagementsystem). Das kann ein SQL Server sein (z.B. PostgreSQL oder MariaDB) oder eine Datenbankbibliothek wie SQLite.
- Falls Sie einen eigenen Webspace haben, verfügt dieser möglicherweise über eine Datenbank und phpmyadmin (ein grafisches Werkzeug zum Administrieren der Datenbank, in dem Sie auch direkt SQL-Befehle eingeben können).
- Falls Sie das Paket XAMPP installiert haben, um einen lokalen Webserver auf ihrem PC zur Verfügung zu haben, verfügen Sie bereits mit dem zu MySQL kompatiblen MariaDB über ein funktionsfähiges Datenbanksystem und mit phpMyAdmin über ein Zugriffstool.
- Sie können MariaDB auch direkt installieren und erhalten dann HeidiSQL als Zugriffsoberfläche dazu
- DB Browser for SQLite ist ein grafisches Werkzeug zum Bearbeiten von SQLite-Datenbanken und unter Windows, Linux und macOS lauffähig. Eine SQLite-Datenbank besteht aus einer einfachen Datei und eignet sich daher gut zum Experimentieren – Löschen und Sichern eines bestimmten Stands der Datenbank stellen kein Problem dar.
Das „Lite“ im Namen von SQLite bezieht sich übrigens auf den geringen Ressourcenverbrauch und die einfache Administrierbarkeit, weniger auf den Funktionsumfang in Bezug auf das Verständnis von SQL. - Wer es lieber direkt auf der Kommandozeile mag, kann das Kommandozeilenwerkzeug von SQLite verwenden.
Angesichts der Vielfalt an DBMS und Tools können wir leider nicht auf die Details zum Umgang mit diesen Programmen eingehen.
Testdaten
Dieses Bild zeigt ein so genanntes „Entity-Relationship“ Modell eines Datenbestandes. Entitäten sind die Dinge, die in der Datenbank gespeichert werden, und Relationen sind die Beziehungen zwischen den Entitäten. Jedes Rechteck steht für einen Entitätstyp, also Dinge, die sich gleichartig beschreiben lassen. Die Ovale daran sind die Attribute, die Eigenschaften, die ein Ding dieses Typs aufweist. Alle Entitäten eines Entitätstyps werden durch den gleichen Satz an Attributen beschrieben: Jeder Student hat eine Matrikelnummer und einen Namen, jede Vorlesung eine Vorlesungsnummer und einen Titel, jeder Professor eine Personalnummer und einen Namen. Zwischen den Entitäten bestehen Beziehungen. Auch hier gibt es verschiedene Typen. Ein Professor hält eine oder mehrere Vorlesungen, jede Vorlesung wird aber von genau einem Professor gehalten. Es ist eine eins-zu-N Beziehung. Zwischen Student und Vorlesung besteht eine m:n Beziehung: Ein Student hört mehrere Vorlesungen, und jede Vorlesung wird von mehreren Studenten gehört.
| Relationen: |
|
|
|
|
|---|
Entitäten und ihre Attribute lassen sich 1:1 auf Zeilen und Spalten von Tabellen abbilden. Jeder Entitätstyp wird in einer eigenen Tabelle gespeichert. Die Entitäten sind Zeilen dieser Tabelle, und jedes Attribut bekommt eine eigene Spalte.
Das Beispiel zeigt je eine Tabelle für Professoren, für Vorlesungen und für Studenten. Eine 1:N Beziehung lässt sich so abbilden, dass man in den Entitäten der N-Seite einen Schlüssel speichert, der zur Entität der 1-Seite gehört. Die Vorlesung-Tabelle enthält deshalb pro Zeile die PersNr des Professors, der diese Vorlesung hält. Bei einer M:N Beziehung ist es schwieriger. Relationale Datenbanken können in einer Zeile keine Listen von Werten speichern. Darum wird die Beziehung über eine Beziehungstabelle hergestellt, die für jede Paarung die Schlüsselwerte der beiden Entitäten enthält. Oft ist es auch so, dass die Beziehungstabelle noch weitere Attribute enthält, die die Beziehung näher beschreiben. Es könnte beispielsweise die Personalnummer des Tutors sein, der einen Studenten bei einer bestimmten Vorlesung betreut.
Abfragen
Einfaches Lesen einer Tabelle mit SELECT und FROM
Um Tabelleninhalte einer relationalen Datenbank zu lesen, verwendet man den SELECT Befehl. Dieser besteht aus mehreren, in ihrer Reihenfolge festgelegten Teilen, auch Klauseln genannt. Jede Klausel beginnt mit einem Schlüsselwort.
Im einfachsten Fall besteht der SELECT Befehl aus einer SELECT- und einer FROM-Klausel:
SELECT *
FROM Student;
Die FROM-Klausel benennt eine oder auch mehrere Tabellen, deren Inhalte gelesen werden sollen. In der SELECT-Klausel wird aufgelistet, welche Spalten dieser Tabellen auszugeben sind. Möchte man alle Spalten haben, kann man für manuelle Auswertungen einfach ein Sternchen hinschreiben.
Ergebnis:
| MatrNr | Name |
|---|---|
| 26120 | Fichte |
| 25403 | Jonas |
| 27103 | Fauler |
Abfrage mit Spaltenauswahl
Braucht man nicht alle Spalten, listet man die gewünschten Spalten einzeln, durch Komma getrennt, auf. Diesen Vorgang nennt man Projektion.
SELECT VorlNr, Titel
FROM Vorlesung;
liest die Spalten VorlNr und Titel aller Zeilen der Tabelle Vorlesung.
Ergebnis:
| VorlNr | Titel |
|---|---|
| 5001 | ET |
| 5022 | IT |
| 5045 | DB |
AS - Abfrage mit Umbenennung
Das Ergebnis eines SELECT ist wieder eine Tabelle. Die Spaltennamen der Tabelle entsprechen zunächst den Spalten der Tabelle, die man im FROM angegeben hat. Das lässt sich durch Hinzufügen von AS ändern.
SELECT MatrNr AS Matrikelnummer, Name
FROM Student;
Der Befehl liest die Spalten MatrNr und Name der Student-Tabelle. In der Ergebnistabelle heißt die MatrNr-Spalte aber Matrikelnummer.
Ergebnis:
| Matrikelnummer | Name |
|---|---|
| 26120 | Fichte |
| 25403 | Jonas |
| 27103 | Fauler |
WHERE - Abfrage mit Filter
Man kann ein Abfrageergebnis auch auf bestimmte Zeilen eingrenzen. Dazu dient die WHERE-Klausel. Sie listet die Bedingungen auf, die die gewünschten Zeilen erfüllen sollen. Sie folgt auf die FROM-Klausel. Der Fachbegriff für diese Eingrenzung ist Selektion.
Die Bedingungen, die hinter WHERE angeführt werden können, bestehen wie in Programmiersprachen aus Operanden und Operatoren. Operanden können Spaltennamen sein oder konstante Werte. Einer der Operatoren ist =, der zu einem logischen WAHR ausgewertet wird, wenn seine Operanden gleich sind:
SELECT VorlNr, Titel
FROM Vorlesung
WHERE Titel = 'ET';
listet VorlNr und Titel aller derjenigen Zeilen der Tabelle Vorlesung auf, deren Titel 'ET' ist.
Es hängt von den Einstellungen der Datenbank ab, ob der = Operator Groß- und Kleinschreibung beim Vergleich beachtet. Es ist aber auf jeden Fall so, dass Leerstellen am Ende einer Zeichenkette ignoriert werden.
Die solchermaßen strukturierte, häufig verwendete Anweisung wird nach den Anfangsbuchstaben auch als „SFW-Block“ bezeichnet.
Ergebnis:
| VorlNr | Titel |
|---|---|
| 5001 | ET |
// statt einer Zeile...
$query = 'SELECT foo, bar FROM table WHERE answer=42';
// mehrere nutzen und Heredoc-Syntax verwenden
$query = <<<SQL
SELECT
foo,
bar
FROM
table
WHERE
answer=42
SQL;
Warum haben wir den HEREDOC-String mit SQL begrenzt und nicht, wie man es zumeist findet, mit END? Auf diese Weise wird deutlich gemacht, dass es sich bei diesem String um SQL handelt und nicht im irgendeinen String. Und vor allem: Editoren wie Visual Studio Code greifen diesen Hinweis auf und schalten ihr Code-Highlighting von PHP auf SQL um! Unser Wiki-Highlighter beherrscht diesen Trick leider nicht.
WHERE und AS - wer gewinnt?
Schauen Sie sich diese Abfrage an:
SELECT Name AS Teilnehmername
FROM Student
WHERE Teilnehmername LIKE 'F%';
Gelingt diese Query? Nein. Oder vielleicht doch, je nachdem, wie hellsichtig Ihre SQL Umgebung ist. Der Normalfall ist jedoch, dass die Query zurückgewiesen wird, weil die Spalte </code>Teilnehmername</code> unbekannt ist. Aliasnamen im SELECT-Teil der Abfrage werden erst zugewiesen, wenn die Spaltenauswahl stattfindet, und das ist bei der Verarbeitung von WHERE noch nicht geschehen.
LIKE - Abfrage mit Filter nach Inhalt
Ein anderer Operator ist LIKE. Er führt einen Mustervergleich durch, ähnlich der Mustersuche nach Dateinamen mit * und ?.
SELECT Name
FROM Student
WHERE Name LIKE 'F%';
listet die Namen aller Studenten auf, deren Name mit F beginnt (im Beispiel: Fichte und Fauler).
LIKE kann mit verschiedenen Platzhaltern verwendet werden: _ steht für ein einzelnes beliebiges Zeichen, % steht für eine beliebige Zeichenfolge. Manche Datenbanksysteme bieten weitere solche Wildcard-Zeichen an, etwa für Zeichenmengen.
Ergebnis:
| Name |
|---|
| Fichte |
| Fauler |
→ Programmiertechnik/Kontextwechsel#Besonderheit:_der_LIKE-Operator
ORDER BY - Abfrage mit Filter und Sortierung
Wenn die Ergebnisse einer Abfrage in einer bestimmten Reihenfolge erwartet werden, kann man sie sortieren lassen. Dafür fügt man am Ende des SELECT Befehl die ORDER BY Klausel an. Sie benennt die Spalten, nach deren Inhalt zu sortieren ist. Ohne weitere Angaben erfolgt die Sortierung aufsteigend, durch Hinzufügen des Schlüsselwortes DESC wird diese Spalte absteigend sortiert.
SELECT Vorname, Name, StrasseNr, Plz, Ort
FROM Student
WHERE Plz = '20095'
ORDER BY Name, Vorname DESC
listet Vorname, Name, StrasseNr, Plz und Ort aller Studenten aus dem angegebenen Postleitzahlbereich sortiert nach Name auf. Studenten mit gleichem Nachnamen werden absteigend nach Vorname sortiert.
Abfrage mit verknüpften Tabellen
Oft müssen für Datenbankabfragen die Inhalte mehrerer Tabellen miteinander kombiniert werden. Der Fachbegriff hierfür ist JOIN. Dabei geht man so vor, dass man mit der zentralen Tabelle der Abfrage beginnt und die nötigen weiteren Tabellen anknüpft:
SELECT Vorlesung.VorlNr, Vorlesung.Titel, Professor.PersNr, Professor.Name
FROM Professor
JOIN Vorlesung ON Professor.PersNr = Vorlesung.PersNr;
Ein JOIN wird standardmäßig so gebildet, dass nur die Zeilen aus Professor- und Vorlesung-Tabelle Verwendung finden sollen, für die die Join-Bedingung erfüllbar ist. Ein Professor, der keine Vorlesung hält, oder eine Vorlesung mit einer in Professor unbekannten PersId würden also nicht aufgelistet werden. Es gibt alternative Join-Verfahren, die im Artikel über Joins beschrieben werden.
Die theoretische Idee einer solchen Verknüpfung ist, dass das DBMS alle möglichen Kombinationen von Professoren und Vorlesungen bildet, das so genanntes kartesische Produkt. Bei 10 Professoren und 20 Vorlesungen wären das 200 mögliche Kombinationen. Wir wollen aber je Professor nur die Vorlesungen haben, die er auch hält, und schränken darum diese Kombinationen in der ON-Bedingung auf diejenigen ein, wo die PersNr des Professors mit der in der Vorlesung gespeicherten PersNr übereinstimmt.
In der Praxis wäre dieses Vorgehen unglaublich aufwändig und kein Datenbankserver geht gemäß der reinen Theorie vor. Das wichtigste Element eines Datenbankservers ist der Query Optimizer, der für solche Querys den bestmöglichen Ausführungsplan findet.
Die JOIN-Syntax ist heute in allen Datenbanken verfügbar, mit Ausnahme einiger Sonderformen in Datenbanken, die auf wenig Speicherverbrauch optimiert sind (wie beispielsweise SQLite).
SELECT Vorlesung.VorlNr, Vorlesung.Titel, Professor.PersNr, Professor.Name
FROM Professor, Vorlesung
WHERE Professor.PersNr = Vorlesung.PersNr;
Die Join-Bedingung (egal ob in ON oder WHERE) kann auf beliebige Weise gestaltet werden. Sie können beliebige Vergleichsoperatoren verwenden, auch SQL-Funktionen sind zulässig. Sie können Spalten der beteiligten Tabellen vergleichen, Sie können aber auch Spaltenwerte mit Konstanten vergleichen.
In ON-Bedingungen ist allerdings zu beachten, dass man darin nur auf diejenigen Tabellen zugreifen kann, die bis zu diesem Punkt eingeführt wurden. Wenn Sie drei Tabellen mit JOIN verknüpfen, können Sie in der ON-Bedingung des zweiten JOIN nicht auf die Tabelle im dritten JOIN zugreifen.
Was das Beispiel auch zeigt, ist der Umgang mit mehrdeutigen Namen. Die Professor- und Vorlesung-Tabelle enthalten beide eine Spalte mit dem Namen PersNr. Würde man ON PersNr = PersNr schreiben, wüsste das DBMS nicht, was gemeint ist. Um das aufzulösen, kann man eine Spalte den Namen der Tabelle voranstellen, in der sie zu finden ist.
Aliasnamen für Tabellen
Wenn die Herkunft eines Spaltennamens nicht eindeutig ist, kann es mühsam werden, immer den vollständigen Tabellennamen hinzuzufügen. Um das zu vereinfachen, erlaubt SQL die Vergabe eines Aliasnamens auch für Tabellen. SQL schaut normalerweise nicht nach vorn, aber Tabellenaliase können auch im SELECT schon benutzt werden (der Grund dafür steht in der Zusammenfassung am Ende dieses Kapitels):
SELECT v.VorlNr, v.Titel, p.PersNr, p.Name
FROM Professor AS p
JOIN Vorlesung v ON p.PersNr = v.PersNr;
Das Schlüsselwort AS ist optional. Bei der Vorlesung Tabelle haben wir es einfach weggelassen.
COUNT & Co - Aggregat-Funktionen
Eine häufige Aufgabe beim Abfragen umfangreicher Datenbestände ist ihre Verdichtung. Man möchte zählen, summieren, Durchschnitte bilden, oder Minima und Maxima finden. SQL unterstützt standardmäßig genau diese fünf Operationen durch die sogenannten Aggregatfunktionen COUNT, SUM, AVG, MIN und MAX. Werden diese Funktionen in einer einfachen SFW-Abfrage eingesetzt, ist das Ergebnis genau eine einzige Zeile. Es ist sinnvoll, die Aggregatfunktionen mit AS zu kombinieren, um den Namen der Ergebnisspalte festzulegen.
SELECT COUNT(*) AS Anzahl, MAX(Name) AS MaxName FROM Professor
Ergebnis:
| Anzahl | MaxName |
|---|---|
| 3 | Wirth |
Das Beispiel soll alle Sätze zählen, darum wird der COUNT-Funktion ein Stern als Argument übergeben. Durch Angabe eines Spaltennamens würden alle Zeilen gezählt, in denen diese Spalte nicht den speziellen Wert NULL enthält.
GROUP BY - Bilden von Teilmengen
Nicht immer will man alle Sätze aggregieren. Man kann auch Teilmengen bilden. Betrachten wir ein etwas umfangreicheres Beispiel:
| MatrNr | Name | PLZ | StudGang |
| 26120 | Schmitz | 50933 | E-Technik |
| 21391 | Meyer | 50933 | Physik |
| 25403 | Jonas | 10365 | Physik |
| 14983 | Eifrig | 10365 | Mathematik |
| 27103 | Fauler | 80769 | E-Technik |
Mit der Abfrage
SELECT StudGang AS Studiengang, COUNT(*) AS Anzahl
FROM Student
GROUP BY StudGang
ORDER BY StudGang
werden die ermittelten Zeilen nach Studiengang gruppiert und die Anzahl gebildet
Ergebnis:
| Studiengang | Anzahl |
|---|---|
| E-Technik | 2 |
| Mathematik | 1 |
| Physik | 2 |
Ohne Angabe einer ORDER BY Klausel ist die Reihenfolge der Sätze nicht definiert. Das Ergebnis kann aufsteigend nach den Gruppierspalten sortiert sein, aber das ist ohne ORDER BY nicht gewährleistet.
DISTINCT - Abfrage mit eindeutigen Werten
Eine Sonderform der Gruppierung ist das Reduzieren einer Ergebnismenge auf eindeutige Werte. Wenn man aus der im vorigen Abschnitt gezeigten, erweiterten Student-Tabelle eine Liste der belegten Studiengänge ermitteln möchte, dann ist
SELECT StudGang FROM Student
falsch – man möchte ja E-Technik und Physik nur einmal ausgeben. Man kann es mit GROUP BY lösen:
SELECT StudGang
FROM Student
GROUP BY StudGang
Aber weil das eine recht häufige Aufgabe ist, gibt es dafür das Schlüsselwort DISTINCT in der SELECT Klausel:
SELECT DISTINCT StudGang FROM Student
DISTINCT bezieht sich nicht auf eine Spalte, sondern auf die komplette Ergebniszeile. Listet man mehrere Spalten auf, werden nur die Zeilen zusammengefasst, bei denen alle Spaltenwerte gleich sind.
DISTINCT lässt sich auch in der Aggregatfunktion COUNT einsetzen:
SELECT COUNT(StudGang), COUNT(DISTINCT StudGang) FROM Student
ermittelt zwei Werte: Die Anzahl der Studenten, für die StudGang nicht NULL ist (ohne DISTINCT) und die Anzahl von unterschiedlicher Studiengängen, die von den Studenten belegt wurden (mit DISTINCT).
HAVING - Filtern von aggregierten Werten
Wenn man die GROUP BY Klausel einsetzt, kann die Aufgabe entstehen, dass man nur die Gruppen sehen möchte, für die ein aggregiertes Ergebnis bestimmte Bedingungen erfüllt. Beispielsweise möchte man alle Studiengänge finden, für die die Menge der eingeschriebenen Studenten eine Mindestmenge unterschreitet. Eine Abfrage, die die Anzahl der Studenten pro Studiengang findet, wurde bereits weiter oben gezeigt. Eine Filterung des COUNT-Ergebnisses mittels WHERE ist aber nicht möglich, weil die WHERE-Filterung vor der Gruppierung stattfindet. Dafür gibt es eine eigene Klausel: HAVING.
SELECT StudGang AS Studiengang, COUNT(*) AS Anzahl
FROM Student
GROUP BY StudGang
HAVING COUNT(*) < 2
ORDER BY StudGang
In der HAVING Klausel muss die zu filternde Spalte genauso spezifiziert werden wie in der SELECT Klausel. Der mit AS angegebene Aliasname für diese Spalte kann im Allgemeinen nicht verwendet werden. MySQL ist hier wieder die Ausnahme, dort wäre HAVING Anzahl < 2 zulässig.
Ergebnis:
| Studiengang | Anzahl |
|---|---|
| Mathematik | 1 |
Für Mathe ist wohl etwas mehr Werbung nötig.
Mengenoperatoren: UNION, EXCEPT und INTERSECT
Mengenoperatoren können dazu genutzt werden, die Ergebnismengen mehrerer SELECT-Abfragen zusammenzufügen. Voraussetzung ist, dass diese SELECTs gleich viele Attribute auslesen und die Datentypen der Attribute übereinstimmen.
SELECT userid, username, lastlogin, 'A-Forum' as Quelle
FROM forum1.users
WHERE userlevel=9
UNION
SELECT userid, username, lastlogin, , 'B-Forum'
FROM forum2.users
WHERE userlevel=9
ORDER BY lastlogin
Das Beispiel würde aus den user-Tabellen zweier DB-Schemas alle User mit Level 9 lesen und als eine Tabelle ausgeben. Um im Ergebnis die Herkunft des Users sehen zu können, wird in den Selects eine vierte Spalte erzeugt, in der eine Konstante eingetragen ist. Der ORDER BY wirkt auf die Gesamtergebnismenge.
- UNION vereinigt die Ergebnismengen der beteiligten SELECT-Abfragen zu einer einzigen Menge. Je nach verwendetem Datenbanksystem gibt es noch die erweiterten Formen UNION DISTINCT und UNION ALL, um anzugeben, ob doppelt vorkommende Ergebnistupel entfernt werden (DISTINCT) oder erhalten bleiben (ALL) sollen. Der Normalfall ist, dass UNION wie UNION DISINCT wirkt und ein UNION ALL explizit angegeben werden muss. Es gibt aber auch Datenbanksysteme, die UNION wie UNION ALL interpretieren und die ALL Option gar nicht erkennen. Die explizite Angabe von DISTINCT wird ebenfalls nicht von allen Datenbanksystemen erkannt. Bitte schauen Sie im Handbuch Ihres Datenbanksystems nach, wie die konkrete Handhabung aussieht.
- EXCEPT nimmt die Tupel, die in der vor EXCEPT stehenden Ergebnismenge enthalten sind und entfernt daraus diejenigen Tupel, die in der Ergebnismenge hinter EXCEPT stehen. Mehrfach vorkommende Ergebnistupel werden entfernt. Einige SQL Dialekte verwenden statt EXCEPT das Schlüsselwort MINUS.
- INTERSECT liefert die Schnittmenge zweier Ergebnismengen. Mehrfach vorkommende Ergebnistupel werden entfernt.
Das häufig verwendete Datenbanksystem MySQL kennt UNION und auch die erweiterten Formen UNION DISTINCT und UNION ALL. Ein einfacher UNION wird wie UNION DISTINCT behandelt. Die Mengenoperatoren EXCEPT und INTERSECT kennt es dagegen nicht, diese Operatoren lassen sich aber mit Hilfe eines JOIN oder Subselect nachbauen.
Zusammenfassung
Zusammengefasst sind die wichtigsten Elemente einer SQL-SELECT-Abfrage wie folgt anzugeben:
SELECT [DISTINCT] Auswahlliste [AS Spaltenalias]
FROM Quelle [ [AS] Tabellenalias]
[WHERE Where-Klausel]
[GROUP BY (Group-by-Attribut)+]
[HAVING Having-Klausel]
[ORDER BY (Sortierungsattribut [ASC|DESC])+];
Erläuterung:
- DISTINCT gibt an, dass aus der Ergebnisrelation gleiche Ergebnistupel entfernt werden sollen. Es wird also jeder Datensatz nur einmal ausgegeben, auch wenn er mehrfach in der Tabelle vorkommt. Sonst liefert SQL eine Multimenge zurück.
- Auswahlliste bestimmt, welche Spalten der Quelle auszugeben sind ( * für alle) und ob Aggregatfunktionen anzuwenden sind. Wie bei allen anderen Aufzählungen werden die einzelnen Elemente mit Komma voneinander getrennt.
- Quelle gibt an, wo die Daten herkommen. Es können Relationen und Sichten angegeben werden und miteinander als kartesisches Produkt oder als Verbund (JOIN, ab SQL-92) verknüpft werden. Mit der zusätzlichen Angabe eines Namens können Tupelvariablen besetzt werden, also Relationen für die Abfrage umbenannt werden).
- Where-Klausel bestimmt Bedingungen, auch Filter genannt, unter denen die Daten ausgegeben werden sollen. In SQL ist hier auch die Angabe von Unterabfragen möglich, sodass SQL streng relational vollständig wird.
- Group-by-Attribut legt fest, ob unterschiedliche Werte als einzelne Zeilen ausgegeben werden sollen (GROUP BY = Gruppierung) oder aber die Feldwerte der Zeilen durch Aggregationen wie Addition (SUM), Durchschnitt (AVG), Minimum (MIN), Maximum (MAX) zu einem Ergebniswert zusammengefasst werden, der sich auf die Gruppierung bezieht.
- Having-Klausel ist wie die Where-Klausel, nur dass sich die angegebene Bedingung auf das Ergebnis einer Aggregationsfunktion bezieht, zum Beispiel HAVING SUM (Betrag) > 0.
- Sortierungsattribut: nach ORDER BY werden Attribute angegeben, nach denen sortiert werden soll. Die Standardvoreinstellung ist ASC, das bedeutet aufsteigende Sortierung, DESC ist absteigende Sortierung.
- die in FROM und JOIN angegebenen Tabellen werden gelesen und miteinander zum kartesischen Produkt ihrer Zeilen verknüpft, unter Beachtung der mit ON formulierten Bedingungen (siehe den Abschnitt zu verknüpften Tabellen)
- die Zeilen des kartesischen Produkts werden durch die WHERE-Bedingungen gefiltert. Gute SQL Server kombinieren Schritt 1 und 2, um nicht sinnlos ein riesiges kartesisches Produkt aufzubauen.
- die Ergebniszeilen können nun an Hand der GROUP BY Angaben zusammengefasst werden. Dazu werden sie nach den Gruppierbegriffen sortiert. Das Ergebnis der Zusammenfassung besteht aus den Gruppierbegriffen und den Ergebnissen der Aggregatfunktionen, die in der Select-Liste verwendet wurden.
- das Ergebnis der Zusammenfassung kann erneut an Hand der HAVING Angaben gefiltert werden
- jetzt erst findet die Auswahl der im SELECT angegebenen Spalten, die Zuweisung der mit AS vergebenen Aliasnamen und die DISTINCT-Filterung statt.
- Spalten, die beim Gruppieren entfallen sind, stehen nicht mehr zur Verfügung.
- Weil Aliasnamen erst jetzt zugewiesen werden, sind sie in den WHERE, GROUP BY und HAVING Klauseln nicht verfügbar
- MySQL/MariaDB sind hier nicht standardkonform.
Zum ersten erlauben sie die Nennung einer nicht gruppierten Spalte. Der Wert, den man erhält, stammt allerdings aus einer zufälligen Zeile der jeweiligen Gruppe!
Zum zweiten erlauben sie in GROUP BY und HAVING die Verwendung von Aliasnamen aus der SELECT-Klausel
- Zum Abschluss kann das Ergebnis limitiert werden. Die Syntax dazu ist unterschiedlich, MySQL verwendet LIMIT am Ende der Query, Microsoft SQL Server eine TOP n Option im SELECT.
Datensätze hinzufügen und ändern
INSERT INTO
Mit INSERT können Sie neue Datensätze hinzufügen:
INSERT INTO <Tabellenname>(<Spaltenname> [, weitere Spaltennamen])
VALUES (<Wert für die erste Spalte> [, weitere Werte])
Hinter VALUES werden alle einzufügenden Werte der Reihe nach aufgelistet. Es wird genau eine neue Zeile erzeugt.
INSERT INTO Professor (PersNr, Name)
VALUES (21, 'Hastig')
Einfügen mehrerer Zeilen:
INSERT INTO <Tabellenname>(<Spaltenname> [, weitere Spaltennamen])
SELECT <Spalte-1> [, weitere Ausgaben]
[FROM ...]
[WHERE ...]
[GROUP BY ...]
[HAVING ...]
UPDATE
Mit UPDATE können Sie Werte innerhalb eines vorhandenen Datensatzes aktualisieren.
UPDATE tabellen_name
SET tabellen_spalte = wert1
WHERE tabellen_spalte = wert2
DELETE
Mit DELETE können Sie Werte innerhalb eines vorhandenen Datensatzes löschen.
DELETE FROM tabellen_name
WHERE spalten_name = wert
Tabellen erzeugen
In den vorhergehenden Kapiteln wurden bestehende Datenbanken ausgelesen und erweitert. Die Datenbanktabellen können mit Programmen wie phpMyAdmin oder auch mit SQL selbst angelegt werden.
Achtung!
Legen Sie regelmäßig Backups an!
CREATE
CREATE TABLE tabellennamen
(
Spaltenname1 datentyp1 [feldeinschränkung]
Spaltenname2 datentyp2 [feldeinschränkung]
[...]
);
http://www.sql-lernen.de/create-table.php
Urheberrechtlicher Hinweis
Dieser Artikel sowie die darin enthaltenen Abbildungen wurden als Bearbeitung eines Artikels der Wikipedia erstellt, der unter den Lizenzbedingungen der Lizenz "Creative Commons Attribution-ShareAlike 3.0 Unported" steht und wird deshalb unter Namensnennung zu den gleichen Bedingungen weitergegeben. Die Autoren des ursprünglichen Artikels gehen aus der Versionsgeschichte bei Wikipedia hervor.
Quellen
- ↑ SELF-Forum: SQL Abfrage: wo liegt mein Fehler Henman von 19.11.2015
Siehe auch
- Datenbank/Primärschlüssel nachträglich setzen
- Artikel aus SEFLTHTML-Aktuell-Tipps und Tricks
- Sortierfolgen in MySQL vorgeben (web.archive.org)
- Datensätze gruppieren mit SQL (web.archive.org)
→ alle Seiten der Kategorie:DBMS und SQL