Erlernen einer Datenbanksprache: Structured Query Language (SQL) I

From DHVLab

Einstieg in SQL

Im vorangehenden Abschnitt sind wir bereits zwei Mal mit der Datenbanksprache SQL in Kontakt gekommen, zum Einen beim Import einer CSV-Datei, zum Anderen bei der Erstellung einer Tabelle. Die beiden zugehörigen SQL-Befehle seien an dieser Stelle zur Erinnerung noch einmal angeführt:

  • Anlegen einer Tabelle in phpMyAdmin (mit fortlaufender ID-Spalte, zugleich Primärschlüssel):

CREATE TABLE Historiker ( historikerID int NOT NULL AUTO_INCREMENT PRIMARY KEY, name varchar(255), vorname varchar(255), einrichtung varchar(255), ort varchar(255) );

  • Import einer CSV-Datei in die Datenbank:

LOAD DATA LOCAL INFILE '[pfad]/[ergänzen]/dateiname.csv' INTO TABLE `tabellenname` FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;

Es ist also an der Zeit, dass wir uns nun umfassend mit der Structured Query Language auseinandersetzen. Ein paar grundlegende Informationen zu SQL:

  • SQL ist semantisch an die englische Umgangssprache angelehnt und besitzt eine relativ einfach aufgebaute Syntax
  • Der Bestandteil "Query" bezieht sich auf eine der Hauptaufgaben der Sprache: Das Abfragen von, in einer Datenbank vorgehaltenen Daten, um sie dem/der Benutzer/in oder einer Anwendersoftware zur Verfügung zu stellen
  • SQL unterscheidet prinzipiell nicht zwischen Groß- und Kleinschreibung. Im Folgenden werden die SQL-Befehle stets in Großbuchstaben geschrieben, um die Syntax besser verständlich zu machen. Dies ist im Anwendungsfall nicht zwangsläufig erforderlich.
  • Abfrageergebnisse werden stets als neue Tabelle ausgegeben und sind beliebig weiter verarbeitbar.

SQL: DDL, DCL und DML

Die Abfragen/Befehle der Datenbanksprache SQL lassen sich in drei Kategorien unterteilen:

  • Data Definition Language (DDL)
  • Data Control Language (DCL)
  • Data Manipulation Language (DML)


DDL:
Der oben angeführte Befehl zur Erstellung einer Tabelle gehört zur DDL, da er ein Datenbankschema definiert. Neben CREATE TABLE existieren in SQL u.a. folgende DCL-Befehle:

SQL-Eingabe Beschreibung
ALTER TABLE Historiker ADD Postleitzahl int(5) Ergänzt in der Tabelle 'Historiker' eine Spalte namens 'Postleitzahl' mit der Länge von 5 Zeichen
DROP TABLE Historiker Löscht die Tabelle 'Historiker'
CREATE INDEX idx_name ON Historiker (name) Zur Beschleunigung der Suche nach Datensätzen in der Tabelle 'Historiker' wird eine Index mit der Bezeichnung idx_name angelegt.
DROP INDEX idx_name Der eben angelegte Index kann selbstverständlich auch wieder gelöscht werden


DCL:
Mit DCL können Berechtigungen innerhalb des DBMS vergeben werden; da dies für uns nicht so sehr von Relevanz ist (noch sind wir keine Datenbank-Admins), werden wir gleich zu DML übergehen.

DML:
Die Datenbearbeitungssprache DML ermöglicht uns das Auswählen (SELECT), Einfügen (INSERT INTO), Ändern (UPDATE) und Löschen (DELETE FROM/TRUNCATE TABLE) von Daten innerhalb von Tabellen[A 1]. Mit dieser Art von Datenbankanfragen werden wir am häufigsten in unserer tagtäglichen Arbeit mit relationalen Datenbanken konfrontiert. Im Folgenden werden wir uns wichtige Datenbankanfragen näher ansehen.

Datenbankanfragen (DML/DQL)

Mit Hilfe von SQL können Anfragen an eine relationale Datenbank gestellt werden[A 2]. Ein Parser zerlegt die Anfrage in ihre einzelnen relationalen Operatoren, um mit Hilfe der daraus gewonnenen Informationen die durch den Nutzer gestellte Anfrage zu beantworten.

Grundform einer Datenbankanfrage

SELECT * (* steht für "all"; es kann auch gezielt nach einen oder mehrere Attributsnamen gesucht werden, durch Kommata getrennt)
FROM (ein oder mehrere Tabellenname)
WHERE (Bedingung)
Optionale Ergänzungen:
GROUP BY (Zusammenfassung mehrerer Zeilen mit demselben Attribut)
HAVING (Bedingung; z.B. nur wenn mehr als drei Vorkommen eines Attributs)
ORDER BY (Sortierung nach einem bestimmten Attribut)

Grundlegende Hinweise zur Grundform einer Datenbankanfrage:

  • Es müssen nicht alle dieser Klauseln in einer Anfrage vorkommen.
  • Die oben angeführte Reihenfolge muss jedoch immer eingehalten werden.
  • Möchten Sie eine abgeschickte Anfrage abändern, so genügt ein Klick auf "Inline bearbeiten" unterhalb des angezeigten SQL-Befehls.
  • Sobald Sie beginnen, eine SQL-Klausel einzugeben, werden Ihnen über die Autovervollständigung Eingabemöglichkeiten angezeigt.
  • Senden Sie eine fehlerhafte SQL-Anfrage ab, wird Ihnen eine Fehlermeldung ausgegeben. Diese kann (muss aber nicht immer) hilfreich sein, um dem Fehler auf den Grund zu gehen (z.B. wenn eine schließende Klammer fehlt oder ein Anführungszeichen falsch gesetzt wurde).
  • Kommentare innerhalb der Anfrage werden durch "--" für das System kenntlich gemacht.
  • Abfrageergebnisse können unmittelbar exportiert bzw. als neue Tabelle abgespeichert werden.


Verschiedene Datenbankanfragen

To Do: SQL-Zeilen als Spoiler eintragen.

Einfache Abfrage

~ Geben Sie eine Anfrage an die Datenbank ein, um sich die Tabelle 'Historiker' komplett ausgeben zu lassen.
SELECT * FROM `historiker`;

Abfrage mit Auswahl der Spalten (= Projektion)

~ Geben Sie eine Anfrage an die Datenbank ein, um sich von der Tabelle 'Historiker' nur die Spalten `vorname` und `name` ausgeben zu lassen.
SELECT `vorname`, `name` FROM `Historiker`;

Distinct-Abfrage

~ Geben Sie eine Anfrage an die Datenbank ein, um sich von der Tabelle 'Historiker' alle vorhandenen Unistandorte nur einmal ausgeben zu lassen (nicht zu verwechseln mit GROUP BY).
SELECT DISTINCT `ort` FROM `Historiker`;

Gefilterte Abfrage

~ Geben Sie eine Anfrage an die Datenbank ein, um sich von der Tabelle 'Historiker' nur die Spalten `vorname` und `name` der Historiker ausgeben zu lassen, die in München wohnhaft sind.
SELECT `vorname`, `name` FROM `Historiker` WHERE `ort` = 'München';


Einschub: Operatoren, Platzhalter, Anführungszeichen

Der "SFW"-Block (SELECT, FROM, WHERE) bzw. die "WHERE-Klausel" erlauben eine Selektion einzelner Zeilen aus einer Tabelle, deren Inhalte einem bestimmten Muster entsprechen.

Für die Selektion stehen verschiedene, i.d.R. beliebig kombinierbare Operatoren zur Wahl (Beispielabfragen siehe unten):

Operator Funktion
= absolute Übereinstimmung zwischen Suchanfrage und Feldinhalt
!= oder <> absolut keine Übereinstimmung zwischen Suchanfrage und Feldinhalt
>= Größer oder gleich
<= Kleiner oder gleich
LIKE relative Übereinstimmung zwischen Suchanfrage und Feldinhalt. Der LIKE-Operator ermöglicht eine trunktierte Suche unter Verwendung von Platzhaltern

Für die trunktierte Suche mit dem LIKE-Operator kommen folgende Platzhalter zum Einsatz:

Platzhalter Funktion (erklärt anhand eines Beispiel)
% beliebig große Anzahl an Zeichen: Sch% -> Schulz; Scholz; Schneider etc.
_ genau ein beliebiges Zeichen: Sch_lz -> Schulz; Scholz
RLIKE ermöglicht die Suche nach regulären Ausdrücken, also einer abstrakten Darstellung von Zeichenketten
NOT LIKE keine relative Übereinstimmung zwischen Suchanfrage und Feldinhalt
AND, OR und / oder
IS NULL, IS NOT NULL[A 3] ermöglicht die Suche nach regulären Ausdrücken, also einer abstrakten Darstellung von Zeichenketten
BETWEEN 'Zahl 1' AND 'Zahl 2' Definition eines numerischen Wertebereichs


Beispielabfragen:
SELECT * FROM `Historiker` WHERE `name` LIKE 'M_mmsen' AND (Ort = 'Berlin' OR Ort = 'Bonn');
SELECT * FROM `Historiker` WHERE `ort` <> 'Berlin';
SELECT * FROM `Historiker` WHERE `postleitzahl` BETWEEN '85000' AND '89000';
SELECT * FROM `Historiker` WHERE `ort` IS NULL;


Wichtiger Hinweis: Gewiss sind Ihnen bereits die unterschiedlichen Anführungszeichen aufgefallen. Daher sei an dieser Stelle zum besseren Verständnis kurz auf die Unterschiede verwiesen[A 4]:

  • Doppelte Anführungszeichen (" ") und einfache Anführungszeichen/Hochkommata (' ') können synonym verwendet werden, um eine Zeichenkette (String), also z.B. einen zu suchenden Text zu kennzeichnen. Sie dürfen jedoch nur einheitlich und nicht gemischt verwendet werden.
  • Backticks[A 5] finden bei Tabellen- und Feldnamen Anwendung (SELECT `name` FROM `Historiker`). Ihre Verwendung ist nicht obligatorisch, es sei denn wenn Tabellen- oder Feldnamen
    • von MySQL missinterpretiert werden könnten (z.B. SELECT `alter`[A 6] FROM `Personen`;) oder
    • ein Leerzeichen enthalten (z.B. `spalte 1`)



Gefilterte Abfrage mit Sortierung

~ Geben Sie eine Anfrage an die Datenbank ein, um sich von der Tabelle 'Historiker' nur die Spalten `vorname` und `name` ausgeben zu lassen, sortiert nach `vorname`
SELECT `vorname`, `name` FROM `Historiker` ORDER BY `vorname`;
Die Anordnung der Gruppierung lässt sich durch die Anfügung DESC (= descending; absteigend) oder ASC (= ascending; aufsteigend) bestimmen. Standardmäßig wird aufsteigend sortiert.

Abfrage unter Zuteilung von Korrelationsnamen

SELECT `plz` AS Postzeitzahl, `ort` AS Universitätsstandort FROM `Historiker` ORDER BY `vorname`;
Bei der Ausgabetabelle werden die entsprechenden Spalten mit den Korrelationsnamen überschrieben. Sinnvoll ist dies v.a. bei der Abfrage mit verknüpften Tabellen (Joins), der wir uns weiter unten zuwenden werden. Alternativ können Aliasnamen auch wie folgt vergeben werden:
SELECT `plz` "Postzeitzahl", `ort` "Universitätsstandort" FROM `Historiker` ORDER BY `vorname`;

Einfügung von Werten in eine bestehende Tabelle

INSERT INTO `Historiker` (`vorname`, `name`) VALUES (Theodor, Mommsen), (Theodor, Schieder);
Soll ein Feld ohne Inhalt bleiben, so kann "NULL" gesetzt oder der entsprechende Feldname weggelassen werden.

INSERT INTO tabelle2 (id, spalte2, spalte3) SELECT id, spalte2, spalte3 FROM tabelle1 WHERE id < 2;
Mit INSERT INTO können in gleicher Weise Datensätze aus einer Tabelle 1 in eine Tabelle 2 überführt werden.

Aktualisierung eines Wertes in einer bestehenden Tabelle

UPDATE `Historiker` SET `vorname` = 'Theodor' WHERE `name` = 'Schieder';
UPDATE `Historiker` SET `vorname` = 'NULL' WHERE `id` = 92;
Um den Inhalt eines Feldes zu löschen wird "NULL" gesetzt.

Löschen eines Tabellenbereiches

DELETE FROM `Historiker` WHERE `id` < 197;

Zwei wichtige Hinweise:

  1. Verwechseln Sie nicht die beiden Zeichen < und > !
  2. Vergessen Sie nicht, eine WHERE-Klausel zu verwenden, da sonst ALLES aus der Tabelle gelöscht wird.
Löschen des gesamten Tabelleninhalts

DELETE FROM `Historiker`
Der DELETE-Befehl ohne WHERE-Klausel tilgt alle Daten, die Tabellenstruktur bleibt jedoch erhalten.
Beachten Sie: Der Befehl wird unwiderruflich durchgeführt; Sie werden vor Absenden des Befehls nicht mehr gewarnt.


Zurück zu Praktischer Einstieg in das DBMS phpMyAdmin ⇐⇒ Weiter zu Erlernen einer Datenbanksprache: Structured Query Language (SQL) II

Anmerkungen

  1. Teilweise wird auch von DQL (Data Query Language) gesprochen, wenn Daten nur abgefragt und nicht manipuliert werden.
  2. Wie bereits bei den anderen Operationen kann in phpMyAdmin auch die Suche ohne den Einsatz von SQL über die entsprechende Suchmaske (via "Suche" in der operativen Leiste) erfolgen. Nach dem Abschicken einer Suchanfrage wird Ihnen jeweils die zugehörige SQL-Anfrage mit ausgegeben.
  3. NULL-Einräge (ohne Inhalt) sind nicht zu verwechseln mit leeren Strings (von der Zeichenlänge 0).
  4. Fileformat: Diese Seite ist allgemein zu empfehlen, wenn man sich über die Kodierung eines Zeichens informieren möchte.
  5. Vgl. hierzu den Eintrag in DH-Lehre
  6. Das Wort alter würde ansonsten als SQL-Operator interpretiert.