SQL Befehle

Um Datenbanken zu benutzen, verwendet man SQL. Im folgenden Beitrag wird diese Sprache näher erläutert.

Hintergrund

SQL (SEQUEL ausgesprochen) steht für Structured Query Language und wurde bei IBM von Donald D. Chamberlin und Raymond F. Boyce basierend auf dem relationalen Modell von Ted Codd in den 1970ern entwickelt.

Basierend auf dieser Sprache könnne wir relationale Datenbanken verwalten. SQL befehle werden in sogenannten Statements aufgeschrieben.

Da SQL für verschiedene Datenbanksysteme verwendet wird (beispielsweise Postgress, SQLite, MySQL) muss zwischen verschiedenen Dialekten unterschieden werden. Im folgenden werden wir uns jedoch auf MySQL beziehen.

Syntax

Grundsätzlich können SQL Befehle groß wie auch klein geschrieben werden. Sie sind also case-insensitive. Jedoch ist es mittlerweile Standard geworden, Befehle in Großbuchstaben zu schreiben. Trotzdem variiert es von Dialekt zu Dialekt wie und wo man auf Großbuchstaben achten muss.

Im Gegensatz zu anderen Sprechen, müssen Strings in single-quotes ('Hallo Welt') angegeben werden. Außerdem endet ein SQL-Statement mit einem Semikolon.

Bestandteile eines SQL-Statements

Elements-SQL-Statement Quelle: Wikipedia

Im folgenden werden SQL-Befehle erläutert. Diese werden Anhand der World-Datenbank des SQLZoos gezeigt.

SELECT

Mit SELECT können Attribute ausgewählt werden, die in der Tabelle enthalten sind. Um alle Attribute abzufragen verwendet man *.

SELECT *

FROM

Mit FROM wird angegeben, aus welcher Tabelle die Daten abgerufen werden sollen.

FROM world

WHERE

Um nur bestimmte Datensätze anzuzsprechen, wird WHERE benutzt.

WHERE name = 'Germany'

Auch logische Operatoren werden unterstützt. Dabei wird gleich jedoch nur mit = dargestellt.

WHERE area > 1000000

Sollten mehrere Bedingungen bestehen, könnnen AND, OR oder XOR verwendet werden, wobei XOR ein exklusives Oder ist.

WHERE area < 1000000 AND continent = 'Europa'

Um nur Teile eines Attributwertes zu definieren, verwendet man %. Die sogenannte wild-card ermöglicht es beispielsweise den Anfangsbuchstaben eines Strings zu definieren.

WHERE  name LIKE 'G%'

LIKE bedeutet, dass entwas ähnlich zu dem angegebenen ist. Auch hierbei gibt es ein NOT LIKE, welches das Gegenteil beschreibt.

Möchte man die Abfrage nur auf einige bestimmte Werte einschränken, so verwendet man IN.

WHERE name IN ('France', 'Germany', 'Italy');

Subqueries

Da es vorkommen kann, dass bestimmte Daten benötigt werden, um eine Abfrage durchzuführen, verwendet man SELECTs innerhalb von SELECTs.

Möchte man herausfinden, welche Länder größer als Deutschland sind, muss zuerst bestimmte werden, wie groß Deutschland ist.

SELECT population
FROM world
WHERE name = 'Germany';
population
80716000

Nun sollen alle Länder aufgelistet werden, die größer als die herausgefundene Bevölkerungsanzahl sind.

SELECT name
FROM world
WHERE population > (
  SELECT population
  FROM world
  WHERE name = 'Germany'
);
name
Bangladesh
Brazil
[…]

Group by

Um Gruppen zu definieren wird GROUP BY verwendet. Möchte ich beispielsweise die Anzahl der Länder pro Kontinent herausfinden, so muss ich die Liste nach Kontinenten sortieren, und jedes Land zählen.

SELECT continent, COUNT(name)
FROM world
GROUP BY continent;

COUNT() gibt die Anzahl der vorhanden Werte wieder.

continent COUNT(name)
Africa 53
Asia 47
Caribbean 11
Eurasia 2
Europe 44
North America 11
Oceania 14
South America 13

Order by

Eine sortierte Ausgabe wird mit ORDER BY erzielt. Dabei wird angeben, nach welchem Attribut die Werte sortiert werden sollen.

Das folgende Statement gibt alle Länder Eurpas sortiert aus.

SELECT name
FROM world
WHERE continent = 'Europe'
ORDER BY name DESC;
name
Vatican City
United Kingdom
Ukraine
Switzerland
Sweden
Spain
[…]

DESC gibt dabei an, dass die Werte absteigend sortiert werden sollen. Der Standard ASC gibt die Werte in der umgekehrten Reihenfolge wieder.

Funktionen

  • COUNT() bestimmt die die Anzahl
  • SUM() bestimmt die Summe
  • MAX() bestimmt das Maximum
  • AVG() bestimmt den Durchschnitt

HAVING

Um die oben aufgelisteten Funktionen auch als Bedingung zu verwenden benutzt man HAVING. Dies beruht auf der Problematik, dass WHERE ausgeführt wird, bevor die Datenbank durchsucht wurde. Möchte man nun aber die oben aufgelisteten Funktionen nutzen, müssen die passenden Datensätze schon gefunden worden sein. Daher wird HAVING benutzt, da es nach dem Festlegen der Datensätze angewandt wird.

SELECT continent
FROM world
GROUP BY continent
HAVING COUNT(name) > 2;
continent
Africa
Asia
Caribbean
Europe
North America
Oceania
South America

JOIN

Häufig kann es vorkommen, dass mehrer Tabellen abgefragt werden müssen. Um dies zu ereichen verwendet man JOIN.

Beispiel

ausgabe(id, zweck, ↑nutzerid) nutzer(id, name)

Es sollen nun alle Ausgaben von ‘Klaus Schmitz’ aufgelistet werden.

SELECT * 
FROM ausgaben 
WHERE nuterid = 
      (SELECT id FROM nutzer WHERE name ='Klaus Schmitz');
id Zweck nutzerid
1 Büromaterial 12
5 Blumenstrauß Frau Werder 12

Jedoch können beide Tabellen zusammengelegt werden:

SELECT * 
FROM ausgaben JOIN nutzer ON (ausgabe.nutzerid = nutzer.id)
WHERE nutzer.name = 'Klaus Schmitz'
id Zweck nutzerid
1 Büromaterial 12
5 Blumenstrauß Frau Werder 12

Das Ergebnis bleibt das gleiche, die Abfrage wird jedoch übersichtlicher.

RIGHT/LEFT JOIN

Es ist durchaus möglich, dass bestimmte Werte nicht existieren. Dadurch sind sie als NULL definiert. Dabei bedeutet NULL die Abwesenheit jeglicher Werte.

Sollte in unserem obigen Beispiel die Tabelle teilweise Ausgaben enthalten, die keinem Nutzer zugeordnet werden können, so ist die nutzerid bei diesen Ausgaben NULL. Man kann dies durch IS NULL abfragen.

Sollten nun die beiden Tabellen mit JOIN zusammengelegt werden, so kann es vorkommen, dass ausgaben übersehen werden, da sie nicht dem Kriterium ausgabe.nutzerid = nutzer.id entsprechen, weil teilweise die nutzerid nicht vorhanden ist. Daher benutzt man RIGHT JOIN bzw. LEFT JOIN. Man definiert dabei eine der beiden Tabellen, mit der gestartet werden soll. Bei RIGHT ist das die rechte und bei LEFT handelt es sich um die linke Tabelle.

SELECT * 
FROM ausgaben LEFT JOIN nutzer ON (ausgabe.nutzerid = nutzer.id)
WHERE name = 'Klaus Schmitz'

SELF JOIN

Genauso wie man zwei unterschiedlich Tabellen mit JOIN verbinden kann, so kann man auch die gleiche Tabelle miteinander joinen. Der Syntax unterscheidet sich nicht von einem normalen JOIN.

Beispiele aus SQL ZOO

Ein CASE WHEN funktioniert wie ein if-Statement in anderen Programmiersprachen.

SELECT name,
    CASE WHEN dept = 1 OR dept = 2
            THEN 'Sci'
         WHEN dept = 2
            THEN 'Art'
         ELSE 'None'
    END
FROM teacher
name CASE WHEN dep..
Shrivell Sci
Throd Sci
Splint Sci
Spiregrain None
Cutflower Sci
Deadyawn None

Das folgende Statement gibt alle Haltestellen in der Stadt Edinburgh wieder, die von der Haltestelle Craiglockhart ereicht werden können. Dafür wird ein SELF JOIN verwendet.

SELECT stopsb.name, a.company, a.num
FROM route a JOIN route b ON (a.company = b.company AND a.num = b.num) 
JOIN stops stopsa ON (stopsa.id = a.stop)
JOIN stops stopsb ON (stopsb.id = b.stop)
WHERE stopsa.name = 'Craiglockhart'
name company num
Bingham LRT 4
Northfield LRT 4
London Road LRT 4
Princes Street LRT 4
Haymarket LRT 4
Craiglockhart LRT 4
Oxgangs LRT 4
[…] […] […]

INSERT

Datensätze werden mit dem INSERT Befehl eingefügt. Dabei besteht ein solches Statement aus verschiedenen Teilen

  1. Die Tabelle, in die der Datensatz eingefügt werden muss
  2. Welche Attributswerte eingefügt werden
  3. Die Werte der Attribute
INSERT INTO nutzer (id, name) Values (3, "SexyBoy23")

UPDATE

Datensätze können auch aktualisiert werden.

UPDATE nutzer SET name = 'Peter Lustig' WHERE id = 3;