Erläuterungen zu SQL-Grundlagen finden Sie in sql.htm.
Hier finden Sie kommentierte einfache Beispiele für SQL-Kommandos.
Bitte verfahren Sie zur Installation Ihrer Datenbank, wie in der zur Datenbank gehörenden Dokumentation beschrieben ist.
Zu MySQL finden Sie für Windows eine kurze Installationsbeschreibung auch unter mysql.htm#InstallationUnterWindows und eine Anleitung zur Anlage einer Database und einer Tabelle unter mysql.htm#CreateDatabase.
Zu PostgreSQL finden Sie für Linux kurze Installationsbeschreibungen und eine Anleitung zur Anlage einer Database und einer Tabelle unter postgresql.htm.
Wenn Sie die folgenden SQL-Kommandos selbst ausprobieren wollen, müssen Sie vorher die drei Beispieltabellen "Personen", "Speisen" und "Bestellung" anlegen.
Bitte laden Sie dafür die Seite sql-commands.sql.htm in Ihren Webbrowser, markieren alles (im Microsoft Internet Explorer z.B. mit "Strg+A"), kopieren alles in den Zwischenspeicher (z.B. mit "Strg+C" oder "Strg+Einfg") und erstellen eine neue Datei "sql-commands.sql", in die Sie alles einfügen (z.B. mit "Strg+V" oder "Umschalt+Einfg"). Bei sehr vielen Datenbanken können Sie diese .sql-Datei an ein mit der Datenbank mitinstalliertes Hilfs- oder Administrationsprogramm übergeben und die enthaltenen SQL-Kommandos so alle in einem Durchgang ausführen (siehe z.B. unter "Ausführen" in mysql.htm). Bei anderen Datenbanken benötigen Sie vielleicht spezielle Hilfs- oder Administrationsprogramme oder müssen eventuell die SQL-Kommandos einzeln ausführen.
Statt über Kommandozeilenprogramme können Sie die SQL-Kommandos natürlich auch über Datenbank-Tools ausführen, zum Beispiel mit SQuirreL.
|
"SELECT * FROM ..." zeigt den kompletten Inhalt der genannten Tabelle,
allerdings ist die Reihenfolge der Zeilen nicht unbedingt reproduzierbar. Deshalb sollten normalerweise hinter "ORDER BY" eine oder mehrere Spaltentitel angegeben werden, nach denen sortiert wird, wie es die unteren beiden Beispiele zeigen. Die untere linke Tabelle ist zuerst nach Abteilungsname sortiert und bei gleichem Abteilungsnamen in zweiter Priorität nach dem Namen. Ähnlich die untere rechte Tabelle, aber hier ist der Abteilungsname in absteigender Reihenfolge sortiert ("DESC" = descent) und innerhalb der gleichen Abteilung der Name weiterhin in aufsteigender Reihenfolge. |
SELECT * FROM Personen ORDER BY Abteilung, Name
|
SELECT * FROM Personen ORDER BY Abteilung DESC, Name
|
|
Statt "SELECT *" (mit Stern) zeigt "SELECT ..., ..." (ohne Stern, mit Spaltennamen) nur die genannten Spalten. Mit "WHERE" wird eine Bedingung definiert, welche einschränkt, welche Zeilen angezeigt werden sollen. Bitte beachten: Einige Datenbanken selektieren Case-sensitiv (unter Beachtung der Groß-/Kleinschreibung), andere nicht. |
|
Die "WHERE"-Bedingung kann mit einer Verknüpfung logischer Operationen gebildet werden (hier mit "AND" und "OR"). |
|
Als Ungleichheitszeichen wird "<>" verwendet. Einige Datenbanken verstehen zusätzlich auch das in Java übliche "!=", aber "<>" ist standardkonformer. |
|
Mit "LIKE" kann eine ungefähre Übereinstimmung gefordert werden. Das Prozentzeichen ("%") dient dabei als Platzhalter für beliebig viele Zeichen. |
|
Der Unterstrich ("_") dient in "LIKE"-Bedingungen als Platzhalter für genau ein Zeichen. |
|
Mit "BETWEEN" kann ein nummerischer Wertebereich definiert werden. |
SELECT * FROM Personen WHERE Abteilung IS NULL
|
Mit "IS NULL" (bzw. mit "IS NOT NULL") werden leere Einträge abgefragt. Achtung, es gibt zweierlei zu beachten: 1.) Leere Strings werden nicht einheitlich behandelt. In einigen Datenbanken (z.B. Oracle) gibt es keine Leerstrings, ein leerer String würde als "NULL"-Wert gespeichert. Aber in anderen Datenbanken (z.B. MySQL) gibt es sowohl "NULL"-Werte als auch leere Strings (mit Länge 0). Um datenbankunabhängig zu programmieren, sollte mit beidem gerechnet werden. 2.) Anders als zum Beispiel bei Java kann es auch bei nummerischen Werten "NULL"-Werte geben. Diese Werte bedeuten nicht die Zahl "0", sondern hier wurde nichts (oder explizit "NULL") eingetragen. Bei der Umwandlung in einen nummerischen Wert ist deshalb eine Sonderbehandlung erforderlich (wenn die Spalte beim Anlegen der Tabelle nicht explizit als "NOT NULL" definiert wurde). |
|
"DISTINCT" kummuliert mehrere Zeilen mit gleichen Spaltenwerten zu einer Zeile. Man erhält also nur unterschiedliche Einträge, es gibt keine doppelten Einträge. Hier im Beispiel sind die vielen Zeilen zum Beispiel zur Abteilung "Entw" zu einer Zeile zusammengefasst. |
|
"COUNT(*)" zählt die Zahl der Zeilen, die die Bedingung erfüllen. Ohne WHERE-Bedingung würde gezählt, wie viele Zeilen die Tabelle beinhaltet. Allerdings sind solche Zahlen mit Vorsicht zu gebrauchen, da wenige Sekunden später vielleicht eine andere Anwendung eine zusätzliche Zeile hinzugefügt oder eine andere entfernt haben könnte. |
|
"GROUP BY" gruppiert die Ergebniszeilen.
Ähnlich wie bei DISTINCT werden Zeilen mit gleichem Gruppierungswert zu einer Zeile zusammengefasst. Bei "GROUP BY"-Kommandos machen hinter "SELECT" nur Tabellenspalten Sinn, die entweder in der Gruppierungsbedingung enthalten sind (im Beispiel die Spalte "Abteilung") oder Aggregatfunktionen (im Beispiel "COUNT(*)"). Hier im Beispiel gibt "COUNT(*)" an, wie viele Zeilen pro Gruppierung zusammengefasst wurden, was gleichbedeutend ist mit der Anzahl Personen pro Abteilung. Wie das Beispiel zeigt, kann die Spaltenüberschrift durch einen direkt nach dem Spaltennamen (bzw. der Aggregatfunktion) folgenden in doppelten Hochkommas ("Gänsefüsschen") eingeschlossenen Text ("...") ersetzt werden, der dann als Spaltentitel gilt, wodurch die Verständlichkeit erhöht werden kann. Leider weicht die Syntax zur Spaltentitelübersetzung bei einigen Datenbanken etwas von der gezeigten ab. |
|
Die mit "GROUP BY" ermittelte Menge an Zeilen kann eingeschränkt werden durch eine "HAVING"-Bedingung. |
|
Die Tabelle "Speisen" ist unsere zweite Beispieltabelle. Die beiden Tabellen "Personen" und "Speisen" werden später über die Tabelle "Bestellung" verknüpft. |
|
"MIN()", "MAX()", "AVG()", "SUM()" und "COUNT()" sind sogenannte Aggregatfunktionen. Sie fassen Werte aus mehreren Zeilen zu einem Wert zusammen. |
|
Die Mitarbeiter einer Firma bestellen Gerichte beim Italiener. Da die Kundendaten bereits aus früheren und für zukünftige Bestellungen gesondert erfasst wurden und die Speisen natürlich ebenfalls in einer Tabelle abgelegt sind, genügt für die Aufnahme der Bestellung eine Tabelle, die lediglich Verweise auf die Kunden und Speisen enthält. "id_Kunde" und "id_Speise" sind sogenannte "Foreign Keys" (Fremdschlüssel), da sie Werte enthalten, die in einer anderen Tabelle als "Primary Key" (Primärschlüssel) definiert sind und so eindeutig Zeilen in der anderen Tabelle spezifizieren. "id_Kunde" enthält nur "id"-Werte aus der Tabelle "Personen" und "id_Speise" enthält nur "id"-Werte aus der Tabelle "Speisen". Die Tabelle ist datenbanktechnisch so korrekt und enthält keinerlei redundanten Daten, allerdings ist sie für den Menschen so schwer verständlich, weshalb wir die Darstellung erweitern wollen. Die untere Tabelle zeigt einen Join dreier Tabellen, der eine korrekte Verknüpfung zwischen den drei Tabellen bildet, allerdings sehr unübersichtlich, da er einfach alle Spalten anzeigt. |
|
|
Anders als obige Tabelle zeigt die links abgebildete Tabelle nur die relevanten Spalten. Ein Join kann zwei oder auch sehr viele Tabellen verknüpfen. Wichtig: Ein Join über n Tabellen benötigt n-1 Verknüpfungsbedingungen zwischen den Tabellen. Für unsere drei Tabellen "Bestellung", "Personen" und "Speisen" benötigen wir die beiden Verknüpfungsbedingungen "id_Kunde = Personen.id" und "id_Speise = Speisen.id". Beachten: Der Spaltenname "id" kommt in den beiden Tabellen "Personen" und "Speisen" vor und ist deshalb nicht eindeutig. In allen nicht eindeutigen Fällen muss der Tabellenname durch einen Punkt abgetrennt vorangestellt werden (im Beispiel: "Personen.id" und "Speisen.id"). Der Einfachheit halber empfiehlt es sich, bei Joins den Tabellennamen immer voranzustellen. |
|
Dieser Join ermittelt, wer wie viele Gerichte bestellt hat und wie viel jeder einzelne bezahlen muss. |
|
Dieser Join ermittelt für den Pizzabäcker, weches Gericht wie oft geliefert werden muss. |
CREATE TABLE A ( id INT, sa VARCHAR(8) ); CREATE TABLE B ( id INT, sb VARCHAR(8) ); INSERT INTO A VALUES ( 1, 'A1' ); INSERT INTO A VALUES ( 2, 'A2' ); INSERT INTO A VALUES ( 5, 'A5' ); INSERT INTO A VALUES ( null, 'A6' ); INSERT INTO B VALUES ( 1, 'B1' ); INSERT INTO B VALUES ( 2, 'B2' ); INSERT INTO B VALUES ( 8, 'B8' ); INSERT INTO B VALUES ( null, 'B9' ); |
Zur Erläuterung der Unterschiede zwischen den Join-Typen "Inner Join", "Left Outer Join" und "Right Outer Join" werden mit den links stehenden SQL-Kommandos zwei besonders kleine Tabellen neu angelegt. |
|
"Inner Join": Beide SQL-Kommandos führen zum identischen Ergebnis. Die zweite Form wird bevorzugt, weil die Join-Bedingung von anderen Where-Bedingungen abgesetzt ist. Das Ergebnis enthält nur Datensätze, bei denen in beiden Tabellen die Werte der Join-Bedingung gefüllt und gleich sind. |
|
"Left Outer Join": Das Ergebnis enthält alle Datensätze der "linken" Tabelle A, auch dann wenn es in der "rechten" Tabelle B keine korrespondierenden Einträge gibt. Normalerweise wird die Anzahl der resultierenden Datensätze also von der "linken" Tabelle bestimmt. Aber beachten Sie: Falls die für die Join-Bedingung verwendete Spalte aus der "rechten" Tabelle nicht unique ist, wenn also Werte mehrfach vorkommen können, dann ist die Anzahl der resultierenden Datensätze höher. |
|
"Right Outer Join": Das Ergebnis enthält alle Datensätze der "rechten" Tabelle B, auch dann wenn es in der "linken" Tabelle A keine korrespondierenden Einträge gibt. Wie leicht erkannt werden kann, liefert "A left join B" dasselbe Ergebnis wie "B right join A". |