Der Begriff »Structured Query Language« bezeichnet eine strukturierte Abfragesprache für relationale Datenbanken. Sie wurde in den 70ern von IBM entwickelt, um die Selektion und Modifikation von Daten in einer Datenbank zu beschreiben. Vielleicht aufgrund der Einfachheit der Sprache setzte sich SQL in der Datenbank-Szene schnell und erfolgreich durch. Inzwischen gibt es wohl keinen namhaften Datenbankanbieter, der nicht auf die eine oder andere Art diesen Standard unterstützt.
Die Spezifikationen von SQL wurden von ANSI und ISO im ANSI-SQL-Standard festgehalten. Sie finden im Internet die aktuelle Spezifikation auf verschiedenen Servern, z.B. unter SQL Standards und weitere Links im Inhaltsverzeichnis.
Anweisungen zur Veränderung der logischen Struktur der Datenbank oder der Tabellen der Datenbank sind
Die vier wichtigsten Kommandos, auch queries genannt, die den Zugriff auf die Daten in einer Datenbanktabelle ermöglichen, sind
Da wir SQL im Zusammenhang mit der Terra-Datenbank im Internet verwenden wollen, sind unsere Einflussmöglichkeiten beschränkt. So ist es uns nicht gestattet, Datensätze in Tabellen einzufügen, zu verändern oder zu löschen. Ebensowenig ist erlaubt Tabellen zu erstellen oder zu löschen. Was von den SQL-Befehlen übrig bleibt ist die Select-Anweisung. Diese Anweisung ist allerdings so umfangreich und mächtig, dass anhand dessen genug über den Aufbau und die Abfrage von Datenbanken lernen werden.
Der wohl wichtigste und komplexeste SQL-Befehl verändert keine Daten. Mit ihm werden Daten aus einer oder mehreren Tabellen lesend verarbeitet. Das Ergebnis des Select sind Daten, die wiederum wie eine Tabelle strukturiert sind.
Wir wollen verschiedene Beispiele betrachten, um die Verwendung der Anweisung zu untersuchen.
|
Frage: |
Welche Länder sind in der Terra Datenbank eingetragen? |
|
SQL: |
Select l_name From Land |
|
Resultat: |
[190] |
|
L_NAME |
|---|
|
Oesterreich |
|
Jemen |
|
Afghanistan |
|
Albanien |
|
Andorra |
|
x |
|
Frage: |
Was ist in der Tabelle Land überhaupt eingetragen? |
|
SQL: |
Select * From Land |
|
Resultat: |
[190] |
|
EINWOHNER |
FLAECHE |
HAUPTSTADT |
L_ID |
L_NAME |
LT_ID |
|---|---|---|---|---|---|
|
7862000,00 |
83845,00 |
Wien |
A |
Oesterreich |
WIE |
|
2360000,00 |
332968,00 |
Aden |
ADN |
Jemen |
ADN |
|
18630000,00 |
647497,00 |
Kabul |
AFG |
Afghanistan |
AFG |
|
3389000,00 |
28748,00 |
Tirana |
AL |
Albanien |
AL |
|
x |
x |
x |
x |
x |
x |
|
Frage: |
Von welchem Land ist Bridgetown die Hauptstadt? |
|
SQL: |
Select l_name From Land Where hauptstadt = 'bridgetown' |
|
Resultat: |
[1] |
|
L_NAME |
|---|
|
Barbados |
|
Frage: |
Wie heißen die Hauptstädte der östereichischen Bundesländer? |
|
SQL: |
Select lt_name, hauptstadt From Landteil Where l_id = 'a' |
|
Resultat: |
[9] |
|
LT_NAME |
HAUPTSTADT |
|---|---|
|
Burgenland |
Eisenstadt |
|
Kaernten |
Klagenfurt |
|
Niederoesterr. |
St.Poelten |
|
Oberoesterr. |
Linz |
|
Salzburg |
Salzburg |
|
Steiermark |
Graz |
|
Tirol |
Innsbruck |
|
Voralberg |
Bregenz |
|
Wien |
Wien |
SELECT [ALL | DISTINCT] spaltenausdruck | *
FROM tabellenausdruck
[WHERE bedingungen]
Distinct unterdrückt doppelte Zeilen im Ergebnis. All (die Standardeinstellung) bewirkt, dass alle, also auch gleiche Zeilen, im Ergebnis erscheinen.
Mit spaltenausdruck wird angegeben, welche Spalten in die Ergebnisrelation (Tabelle) aufgenommen werden. Mit * werden alle mögliche Spalten einer Tabelle ausgewählt. Die Spaltenüberschrift kann durch Eingabe eines Spaltenbezeichners geändert werden.
Select lt_name As Landteil, hauptstadt From Landteil Where l_id = 'a'
(Vergleiche mit Beispiel 4)
|
Landteil |
HAUPTSTADT |
|---|---|
|
Burgenland |
Eisenstadt |
|
... |
... |
Standard-SQL erlaubt die Benutzung von fünf Funktionen im spaltenausdruck:
|
Funktion |
Bedeutung |
|---|---|
|
Count |
Anzahl der Werte in der Spalte |
|
Sum |
Summe der Werte in der Spalte |
|
Avg |
Mittelwert der Spalte |
|
Max |
größter Wert in der Spalte |
|
Min |
kleinster Wert in der Spalte |
|
Frage: |
Wie viele Städte sind in Spanien eingetragen? |
|
SQL: |
Select Count(st_name) From Stadt Where l_id = 'e' |
|
Resultat: |
[1] |
|
Expr1000 |
|---|
|
4 |
|
Frage: |
Wie viele Einwohner hat die Stadt Deutschlands mit den wenigsten Einwohner? |
|
SQL: |
Select Min(einwohner) As Minimum From Stadt Where l_id = 'd' |
|
Resultat: |
[1] |
|
Minimum |
|---|
|
21530 |
Und als Kombination der beschrieben Möglichkeiten:
|
Frage: |
Welche deutsche Stadt hat die wenigsten Einwohner? |
|
SQL: |
Select st_name As Stadt |
|
Resultat: |
[1] |
|
Stadt |
|---|
|
Dillingen |
oder alle Angaben
|
SQL: |
Select * |
|
Resultat: |
[1] |
|
ST_NAME |
EINWOHNER |
L_ID |
LT_ID |
LAENGE |
BREITE |
|---|---|---|---|---|---|
|
Dillingen |
21530,00 |
D |
SAR |
|
|
Mit tabellenausdruck wird festgelegt, in welchen Tabellen nach den Daten gesucht wird.
Bevor wir mit der formalen Syntax des Tabellenausdrucks fortfahren, hier zunächst eine Übersicht seiner Einzelteile:
|
FROM |
definiert die Eingangstabellen |
|
WHERE |
selektiert aufgrund einer Bedingung die Zeilen der Eingangstabellen |
|
GROUP BY |
gruppiert Zeilen auf der Basis gleicher Spaltenwerte |
|
HAVING |
selektiert nur Gruppen im GROUP-BY-Teil laut einer Bedingung |
|
Frage: |
Welche Länder (Namen, Einwohnerzahl) liegen nicht nur auf einem Kontinent? |
|
SQL: |
Select Distinct l.l_name, l.einwohner |
|
Resultat: |
[3] |
|
L_NAME |
EINWOHNER |
|---|---|
|
Aegypten |
42000000 |
|
Russland |
148700000 |
|
Tuerkei |
59597000 |
werden in der WHERE- und HAVING-Klausel benötigt, um bestimmte Spalten zu selektieren bzw. zu gruppieren. Eine solche Suchbedingung besteht meist aus einer Reihung von Prädikaten, die mit AND oder OR verbunden werden. Durch Klammerung wird eine bestimmte Abarbeitungsreihenfolge erzwungen.
Man unterscheidet sieben Arten von Prädikaten:
Vergleichsprädikat (=)
Intervallprädikat (Between):
|
Frage: |
Welche deutschen Kleinstädte sind eingetragen? |
|
SQL: |
Select st_name, einwohner |
|
Resultat: |
[28] |
|
ST_NAME |
EINWOHNER |
|---|---|
|
Aschaffenburg |
66152 |
|
Bernburg |
71690 |
|
Brandenburg |
84493 |
|
... |
|
Ähnlichkeitsprädikat (Like):
|
Frage: |
Welche Städte besitzen furt im Namen? |
|
SQL: |
Select st_name |
|
Resultat: |
[5] |

|
st_name |
|---|
|
Erfurt |
|
Frankfurt/M |
|
Frankfurt/O |
|
Klagenfurt |
|
Schweinfurt |
Test auf leere Einträge (Null)
Welche Städte haben keine Einwohner? [25]
Select st_name From Stadt Where einwohner Is Null
IN-Prädikat
Gesucht sind alle Städte in Deutschland und Österreich. [122]
Select st_name From Stadt Where l_id In ('d', 'a')
Während die Wirkung der meisten Prädikatarten selbsterklärend ist, bedürfen das ALL-oder-ANY-Prädikat und das EXISTS-Prädikat einer zusätzlichen Erklärung:
ALL- oder-ANY-Prädikat:
Das ALL-oder-ANY-Prädikat läßt sich am besten an einem Beispiel verdeutlichen:
|
Frage: |
Welche Länder haben größere Städte als Japan? |
|
SQL: |
Select Distinct l.l_name, l.l_id oder einfacher: Select Distinct l_id |
|
Resultat: |
[2] |
|
L_NAME |
|---|
|
Mexiko |
|
Vereinigte_Staaten_von_Amerika |
Zunächst wird die Ergebnismenge des Subselects ( Select einwohner From Stadt Where l_id = 'j' ) die Einwohnerzahlen der japanischen Städte errechnet. Danach werden im äußeren Select die Länderkennungen der Länder selektiert, deren Städte Einwohnerzahlen größer als der japanischer Städte haben.
EXISTS-Prädikat
|
Frage: |
Welche deutschen Städte liegen an einem Fluss? Wieviele Einwohner haben diese Städte? |
|
SQL: |
Select st_name, einwohner |
|
Resultat: |
[113] |
|
ST_NAME |
EINWOHNER |
|---|---|
|
Aachen |
247792 |
|
Aschaffenburg |
66152 |
|
Augsburg |
258457 |
|
... |
... |
|
Zittau |
29373 |
Wie viele Städte liegen in Bayern? [21]
Welche Städte haben mehr als 850.000 Einwohner? [166]
Welche Städte haben ein tz im Namen? [3]
Welche Städte haben keine Einwohner? [25]
Welche Länder haben Hauptstädte, die mit m beginnen? [21]
Welche Länder haben mehr 1 Mio., aber weniger als als 10 Mio. Einwohner und eine Hauptstädte, die mit m beginnt. [7]
<< Dieser Absatz ist noch unvollständig. >>
<< Dieser Absatz ist noch unvollständig. >>
Select [ All | Distinct ] columnexpr [, columnexpr ] ...
[ Into :hostvar [, :hostvar ] ... ]
From tablename correlation [, tablename correlation ] ...
Where whereexpr
[ Order By orderkey [ Asc | Desc ] [, orderkey [ Asc | Desc ] ] ...
[ For Read Only | For Fetch Only ]
[ Group By
{
groupexpr [, groupexpr ] ... |
Grouping Sets ( groupexpr [, groupexpr ] ... ) |
Rollup ( groupexpr [, groupexpr ] ... ) |
Cube ( groupexpr [, groupexpr ] ... )
} ...
[ Having havingexpr ]
[ For [Read Only | Fetch Only ] | Update [ Of column [, column ] ] ]
[ Optimize For numrows { Rows | Row } ]
{ simpleselect | ( complexselect ) | valueclause }
[ Union [ All ] | Except [ All ] | Intersect [ All ]
{ simpleselect | ( complexselect ) | valueclause } ]
{ [schemaname.]tablename.columnname |
tabledesignator.columnname | columnname | expr }
[schemaname.]tablename | tabledesignator
Dabei bezieht sich schemaname auf den Namen des Schemas, das die Tabelle oder Sicht besitzt. Wenn schemaname nicht angegeben wird, wird das Vorgabeschema verwendet. tablename bezieht sich auf den Namen der Tabelle oder Sicht, die bei der Erfüllung der Abfrage verwendet wird. tabledesignator wird verwendet, wenn ein alternativer Name für die Tabelle in der Abfrage zur Verfügung gestellt werden soll. TipCube(a,b)
Diese Anweisung ist dementsprechend äquivalent mit Grouping Sets ((a,b), (a),(b),()). Beachten Sie, dass es sich bei groupexpr auch um ein leeres Klammernpaar () handeln kann, wenn innerhalb der Klauseln Grouping Sets, Rollup oder Cube die Gesamtsumme repräsentiert werden soll. Die Having-Klausel enthält einen Ausdruck, der bestimmt, ob aggregierte Ergebnisse zurückgegeben werden sollen. Typischerweise wird sie eingesetzt, um zu ermitteln, ob die zwischenzeitliche Gruppierung einer Group By-Klausel zurückgegeben werden soll. Wenn die Klausel Group By nicht angegeben wird, werden die Ergebnisse für die gesamte Select-Anweisung zurückgegeben. In havingexpr muss eine Aggregatfunktion enthalten sein, die sich auf eine zu gruppierende Spalte bezieht. Die Klauseln For Read Only und For Fetch Only bedeuten dasselbe. Sie können eine cursor-positionierte Delete- oder Update-Anweisung auf die Ergebnisse einer Select-Anweisung anwenden, wenn eine der beiden Klauseln angegeben wird. Dies kann der Leistungssteigerung dienen, weil der Datenbank-Manager keine Exklusivsperren vornehmen muss. Die Klausel For Update legt die Spalten der ausgewählten Reihen fest, die aktualisiert werden können. Wenn keine Spalten angegeben werden, wird von allen aktualisierbaren Spalten ausgegangen. Diese Information wird von der Abfrageoptimierung zur Leistungsverbesserung ausgewertet. Die Klausel Optimize For gibt die erwarteterweise zurückgegebene Anzahl von Reihen an. Ohne Angabe geht die Abfrageoptimierung davon aus, dass alle Reihen der Tabelle ausgewählt werden. Die Angabe einer kleineren Anzahl von Reihen kann zu einer erheblichen Leistungssteigerung führen. Wenn die Anzahl der zurückgelieferten Reihen den angegebenen Wert überschreitet, läuft die Abfrage zwar weiterhin, jedoch gegebenenfalls nur unter deutlichem Geschwindigkeitsverlust.{ [schemaname.]tablename.columnname |
tabledesignator.columnname | columnname | expr [ [ As ] newcolummn ] }
Cube(a,b)
Diese Anweisung ist dementsprechend äquivalent mit Grouping Sets ((a,b), (a),(b),()). Beachten Sie, dass es sich bei groupexpr auch um ein leeres Klammernpaar () handeln kann, wenn innerhalb der Klauseln Grouping Sets, Rollup oder Cube die Gesamtsumme repräsentiert werden soll. havingexpr: Ein logischer Ausdruck, der dazu führt, dass nur Reihen, für die dieser wahr (True) ist, zurückgegeben werden. numrows: Die Anzahl der erwarteterweise von der Abfrage zurückgegebenen Reihen. Ohne Angabe gilt die Anzahl der Reihen in der Tabelle für diesen Wert als Vorgabe. Das Überschreiten dieses Wertes kann zu Leistungseinbußen führen. Wenn Sie jedoch die Rückgabe relativ weniger Reihen erwarten, können Sie die Leistung unter Umständen signifikant verbessern. [Freeze]