Abschnittsübersicht

  • Hervorgehoben
    • Bearbeiten wir nun ein zentrales Problem bei der Verwaltung von Daten: Wie können wir gezielt Informationen aus einer Datenbank gewinnen? Dazu verwenden relationale Datenbankmanagementsysteme die Datenbanksprache SQL. Wir lernen sie zunächst spielerisch kennen – auf geht es nach SQL Island!

    • Lösungen SQL-Island Datei
    • Lösungen SQL-Island (Video) Link/URL
    • CC BY SA 4.0, Dicklyon, https://commons.wikimedia.org/wiki/File:Don_Chamberlin.jpgMithilfe der Datenbanksprache SQL können Datenstrukturen definiert sowie Daten abgefragt und verändert werden.

      Diese Sprache wurde in den 1970er Jahren von Donald D. Chamberlin (ACM Software System Award 1988) und Raymond F. Boyce, basierend auf den Arbeiten von Edgar F. Codd (Turing Award 1981) bei IBM im Rahmen eines Forschungsprojektes entwickelt und 1987 international standardisiert. Im Gegensatz zu den bisher im Unterricht behandelten imperativen Programmiersprachen beschreibt eine SQL-Abfrage, welches Ergebnis gesucht wird, nicht jedoch die einzelnen Verarbeitungsschritte, mit denen das Datenbankmanagementsystem dieses Ergebnis erzeugt. SQL ist daher eine deklarative Sprache.

      SQL-Anweisungen lassen sich nach ihrem Zweck in verschiedene Gruppen einteilen. Die genaue Einteilung unterscheidet sich teilweise zwischen den Darstellungen. Für unseren Unterricht unterscheiden wir zunächst:

      • DDL – Data Definition Language
        Befehle zur Definition von von Datenbankstrukturen
      • DML – Data Manipulation Language
        Befehle zur Datenmanipulation
      • DQL - Data Query Language
        Befehle zur Abfrage von Daten

      Zunächst arbeiten wir mit bereits vorhandenen Datenbanken. Deshalb beschäftigen wir uns zuerst mit der Abfrage von Daten.

      Bild: Dicklyon, CC BY-SA 4.0 via Wikimedia Commons

    • Datenabfragen mit SQL

       
      GK: SELECT-Befehl

      Die SQL-Abfrage erfolgt mit dem Befehl SELECT unter Angabe von bis zu fünf Komponenten. Die allgemeine Syntax hat die Gestalt:

      SELECT [DISTINCT] * | <Attributliste>
      FROM <Tabelle oder Verbund>
      [WHERE <Boolescher Ausdruck]
      [ORDER BY <Attributliste> [ASC | DESC]]
      [LIMIT Zahl [[OFFSET Zahl]]

      SQL-SSyntaxdiagramm

      Die schwierige Syntax lässt sich wie folgt verstehen:

      Klausel Erläuterung
      SELECT [DISTINCT] Wähle die Werte aus der/den Spalte [mehrfache Datensätze nur einmal] ...
      FROM ... aus der Tabelle bzw. den Tabellen ...
      WHERE ... wobei die Bedingung(en) erfüllt sein soll(en) ...
      ORDER BY [ASC/DESC] ... und sortiere nach den Spalten [auf- bzw. absteigend] ...
      LIMIT ... und zeige nur eine bestimmte Anzahl von Datensätze an.
       
      LK: SELECT-Befehl

      Die SQL-Abfrage erfolgt mit dem Befehl SELECT unter Angabe von bis zu sieben Komponenten. Die allgemeine Syntax hat die Gestalt:

      SELECT [DISTINCT] * | <Attributliste>
      FROM <Tabelle oder Verbund>
      [WHERE <Boolescher Ausdruck]
      [GROUP BY <Attributliste>]
      [HAVING <Bedingung>]
      [ORDER BY <Attributliste> [ASC | DESC]]
      [LIMIT Zahl [[OFFSET Zahl]]
       
       

      SQL-Syntaxdiagramm LK

      Die schwierige Syntax lässt sich wie folgt verstehen:

      Klausel Erläuterung
      SELECT [DISTINCT] Wähle die Werte aus der/den Spalte [mehrfache Datensätze nur einmal] ...
      FROM ... aus der Tabelle bzw. den Tabellen ...
      WHERE ... wobei die Bedingung(en) erfüllt sein soll(en) ...
      GROUP BY ... und fasse Zeilen mit gleichen Werten der angegebenen Attribute zu Gruppen zusammen ...
      HAVING ... wobei darin folgende zusätzliche Bedingung(en) gelten müssen/muss ...
      ORDER BY [ASC/DESC] ... und sortiere nach den Spalten [auf- bzw. absteigend] ...
      LIMIT ... und zeige nur eine bestimmte Anzahl von Datensätze an.
       
       
      Auswahl von Zeilen - Selektion

      Aus der Tabelle Schüler sollen alle Zeilen ausgewählt werden, in denen der Name "Müller" steht. Diese Auswahl von Zeilen entspricht in der Relationenalgebra einer Selektion.
      (Die Selektion hat also die Form SName = 'Müller'(Schüler))

      Die Umsetzung in SQL lautet: 

      SELECT * 
      FROM Schüler
      WHERE Name = 'Müller';
      Schüler   Ergebnis
      SNr Vorname Name
      4711 Paul Müller
      0815 Erich Schmidt
      7472 Sven Lehmann
      1234 Olaf Müller
      2313 Jürgen Paulsen

      SNr Vorname Name
      4711 Paul Müller
      1234 Olaf Müller
       

      Die WHERE-Klausel liefert also die Selektion. Um zu zeigen, dass alle Spalten angezeigt werden sollen, wird das Stern-Symbol verwendet.

      Nun sollen aus der Tabelle Schüler alle Zeilen selektiert werden, in denen der Name "Müller" steht und deren Vorname mit "O" beginnt. 
      (Die Selektion hat also die Form SName = 'Müller' UND Vorname beginnt mit 'O'(Schüler))

      Die Umsetzung in SQL lautet: 

      SELECT * 
      FROM Schüler
      WHERE Name = 'Müller' AND Vorname LIKE 'O%';
      Schüler   Ergebnis
      SNr Vorname Name
      4711 Paul Müller
      0815 Erich Schmidt
      7472 Sven Lehmann
      1234 Olaf Müller
      2313 Jürgen Paulsen

       →

      SNr Vorname Name
      1234 Olaf Müller
       

      Bedingungen lassen sich mit AND, OR und NOT verknüpfen. Das Prozentsymbol steht als Platzhalter für eine beliebige Folge von Zeichen. Das Prozentzeichen % steht für eine beliebige Folge von Zeichen, auch für eine leere Zeichenfolge. Der Unterstrich _ steht für genau ein beliebiges Zeichen. LIKE wird verwendet im Sinne von "SO WIE". 

      Operator Erklärung
      = < <= >= > <> Vergleicht einen Attributwert mit einem anderen Attributwert oder einer Konstanten. 
      gleich, kleiner als, kleiner gleich, größer gleich, größer, ungleich
      BETWEEN ... AND ... prüft, ob ein Attributwert zwischen zwei Grenzen einschließlich der Grenzwerte liegt
      IN (..., ..., ...) prüft, ob ein Attributwert in einer angegebenen Werteliste enthalten ist
      LIKE

      vergleicht Zeichenketten mit Mustern unter Verwendung der Platzhalter:
      %: für beliebige Zeichen
      _: für genau ein Zeichen

      Ob dabei Groß- und Kleinschreibung unterschieden werden, hängt vom verwendeten Datenbanksystem und dessen Einstellungen ab.

      IS (NOT) NULL prüft, ob für ein Attribut kein Wert (NULL) bzw. ein Wert vorhanden ist.
       
      Auswahl von Spalten - Projektion

      Aus der Tabelle Schüler sollen nur die Spalte mit dem Attribut "Name" ausgewählt werden. Diese Auswahl von Spalten entspricht in der Relationenalgebra einer Projektion.
      (Die Projektion hat also die Form PName(Schüler))

      Die Umsetzung in SQL lautet: 

      SELECT Name
      FROM Schüler; 
      Schüler   Ergebnis
      SNr Vorname Name
      4711 Paul Müller
      0815 Erich Schmidt
      7472 Sven Lehmann
      1234 Olaf Müller
      2313 Jürgen Paulsen

      Name
      Müller
      Schmidt
      Lehmann
      Müller
      Paulsen

      Mit DISTINCT werden Mehrfachvorkommen entfernt.

      Die Umsetzung in SQL lautet: 

      SELECT DISTINCT Name 
      FROM Schüler; 
      Schüler   Ergebnis
      SNr Vorname Name
      4711 Paul Müller
      0815 Erich Schmidt
      7472 Sven Lehmann
      1234 Olaf Müller
      2313 Jürgen Paulsen

      Name
      Müller
      Schmidt
      Lehmann
      Paulsen

       

      Hintereinanderausführung von Projektion und Selektion

      Aus der Tabelle Schüler sollen die Vornamen aller Schüler angezeigt werden, deren Nachname Müller ist. 
      (Die Abfrage hat also die Form PVorname(SName = 'Müller'(Schüler)))

      Die Umsetzung in SQL lautet: 

      SELECT Vorname 
      FROM Schüler
      WHERE Name = 'Müller';
      Schüler   Ergebnis
      SNr Vorname Name
      4711 Paul Müller
      0815 Erich Schmidt
      7472 Sven Lehmann
      1234 Olaf Müller
      2313 Jürgen Paulsen

      Vorname
      Paul
      Olaf
       

      In der zugehörigen Relationenalgebra wird zunächst die Selektion und anschließend die Projektion ausgeführt. Auch bei SQL wird logisch zunächst festgelegt, aus welchen Daten (FROM) und unter welchen Bedingungen (WHERE) Zeilen berücksichtigt werden. Erst anschließend bestimmt SELECT, welche Spalten im Ergebnis erscheinen.

      Inner Join in SQL

      Die Tabellen Schüler und Kurse sollen über das gemeinsame Attribut SNr miteinander verbunden werden. Im Ergebnis erscheinen nur die Kombinationen von Zeilen, für die die angegebenen Werte von SNr übereinstimmen. 
      (Die Abfrage hat also die Form JSchüler.SNr = Kurs.SNr(Schüler, Kurse))

      Die Umsetzung in SQL lautet:

      SELECT * 
      FROM Schüler INNER JOIN Kurse
      ON Schüler.SNr = Kurse.SNr;
      Schüler Kurse   Ergebnis
      SNr Vorname Name
      4711 Paul Müller
      0815 Erich Schmidt
      7472 Sven Lehmann
      1234 Olaf Müller
      2313 Jürgen Paulsen
      SNr KNr Fehlzeit Punkte
      0815 03 0 12
      4711 03 12 03
      4711 09 8 05
      1234 23 3 14

       →

      SNr Vorname Name SNr KNr Fehlzeit Punkte
      4711 Paul Müller 4711 03 12 03
      4711 Paul Müller 4711 09 8 05
      0815 Erich Schmidt 0815 03 0 12
      1234 Olaf Müller 1234 23 3 14
       

      Da mit SELECT * alle Spalten beider Tabellen ausgegeben werden, erscheint das Verknüpfungsattribut SNr im Ergebnis zweimal. Ein solches Ergebnis wird in der Regel nicht gewünscht. Es genügen oft nur einige Spalten des Verbundes. Existieren zu einer Zeile der ersten Tabelle mehrere passende Zeilen der zweiten Tabelle, entstehen entsprechend mehrere Ergebniszeilen.

      Aus den Tabellen Schüler und Kurse sollen alle Schülernamen mit ihren Fehlzeiten aufgelistet werden. Der Befehl lautet:

      SELECT Schüler.Vorname, Schüler.Name, Kurse.KNr, Kurse.Fehlzeit 
      FROM Schüler INNER JOIN Kurse
      ON Schüler.SNr = Kurse.SNr 
      ORDER BY Kurse.Fehlzeit DESC;
      Ergebnis
      Vorname Name KNr Fehlzeit
      Paul Müller 03 12
      Paul Müller 09 8
      Olaf Müller 23 3
      Erich Schmidt 03 0
       

    • nur im LK: Outer Join in SQL

      Bei einem INNER JOIN erscheinen nur diejenigen Zeilen im Ergebnis, für die in beiden Tabellen passende Datensätze vorhanden sind. Manchmal sollen jedoch auch Datensätze ohne passenden Partner angezeigt werden. Dazu dienen äußere Verbunde (OUTER JOIN).

      Beispiel: Für alle Schülerinnen und Schüler soll der Status der Spindvermietung angezeigt werden. Auch Schülerinnen und Schüler ohne gemieteten Spind müssen daher im Ergebnis erscheinen.

      Da die Tabelle Schüler links steht und vollständig erhalten bleiben soll, verwenden wir einen LEFT JOIN. Das verbindende Attribut lautet SNr. 

      Der SQL-Befehl lautet:

      SELECT * 
      FROM Schüler LEFT JOIN Spind
      ON Schüler.SNr = Spind.SNr;
      Schüler Spind   Ergebnis
      SNr Vorname Name
      4711 Paul Müller
      0815 Erich Schmidt
      7472 Sven Lehmann
      1234 Olaf Müller
      2313 Jürgen Paulsen
      ID SNr Ort Beginn
      101   A2  
      102 4711 A1 2020-08-03
      103 4711 A1 2020-08-23
      104 1234 A2 2019-10-01
      105   A3  

       

       →

      SNr Vorname Name ID Ort Beginn
      4711 Paul Müller 102 A1 2020-08-03
      4711 Paul Müller 103 A1 2020-08-23
      0815 Erich Schmidt      
      7472 Sven Lehmann      
      1234 Olaf Müller 104 A2 2019-10-01
      2313 Jürgen Paulsen      
       
       

      Für jede Zeile aus Schüler werden passende Daten aus Spind ergänzt. Existiert kein passender Spinddatensatz, enthalten die Attribute aus Spind im Ergebnis den Wert NULL.

      Sollen nur die Schülerinnen und Schüler ermittelt werden, die keinen Spind gemietet haben, können genau diese Zeilen ausgewählt werden:

      SELECT Schüler.SNr 
      FROM Schüler LEFT JOIN Spind
      ON Schüler.SNr = Spind.SNr
      WHERE Spind.ID IS NULL;

      Ein RIGHT JOIN arbeitet entsprechend mit der rechten Tabelle. SQLite unterstützt außerdem FULL OUTER JOIN, bei dem alle Zeilen beider Tabellen erhalten bleiben.

    • LK: SQL-Befehle zum Einfügen, Löschen und Ändern von Datensätzen

      Neben Abfragen mit SELECT können mit SQL auch Datensätze eingefügt, geändert und gelöscht sowie komplette Tabellen erzeugt werden.

      Einfügen eines Datensatzes mit Angabe der Attribute

      INSERT

       
      INSERT INTO tabelle (attribut1, attribut2, ...)
      VALUES (wert1, wert2, ...);
       

      Die Reihenfolge der Werte muss der Reihenfolge der angegebenen Attribute entsprechen.

      Einfügen eines vollständigen Datensatzes ohne Attributliste

       
      INSERT INTO tabelle
      VALUES (wert1, wert2, ...);
       

      Dabei müssen die Werte genau in der Reihenfolge der Attribute des Tabellenschemas angegeben werden.

      Löschen von Datensätzen

      DELETE

       
      DELETE FROM tabelle
      WHERE bedingung;
       

      Achtung: Fehlt die WHERE-Klausel, werden alle Datensätze der Tabelle gelöscht.

      Ändern von Datensätzen

      UPDATE

       
      UPDATE tabelle
      SET attribut1 = wert1, attribut2 = wert2, ...
      WHERE bedingung;
       

      Achtung: Fehlt die WHERE-Klausel, wird die Änderung auf alle Datensätze der Tabelle angewendet.

      Erzeugen einer neuen Tabelle

      Create

      integritätsbedingungen:

      Integrität

       
      CREATE tabelle (
        attribut1 TYP [integritätsbedingung],
      ...
      PRIMARY KEY (attribut(e))
      [FOREIGN KEY (attribut REFERENCE tabelle.attribut]

      [FOREIGN KEY ...]

    • Übungen