SQL lernen: Einführung mit Beispielen

Die Syntax der Programmiersprache SQL baut auf der relationalen Algebra auf und unterscheidet sich daher auf vielfältige Weise von anderen Programmiersprachen. Um SQL zu lernen, sind Kenntnisse über diese Syntax sowie anschauliche Beispiele äußerst hilfreich.

Grundlagen der SQL-Syntax

Generell versteht man unter Syntax die „Schreibweise“ einer Programmiersprache. Die Syntax legt fest, welche Arten von grundlegenden Code-Konstrukten es gibt und wie sich diese miteinander verknüpfen lassen. Das Verständnis der Syntax ist eine grundsätzliche Voraussetzung zum Lesen und Schreiben von Code in der jeweiligen Sprache.

Die wichtigsten Syntax-Konstrukte in SQL sind SQL-Anweisungen mit ggf. darin enthaltenen Klauseln. Obwohl technisch nicht ganz korrekt, werden beide im Allgemeinen als „SQL-Befehle“ bezeichnet. Daneben existieren weitere Syntax-Konstrukte, die wir der Übersicht halber darstellen:

Begriff Englische Entsprechung Erklärung Beispiel
Anweisung Statement Weist das DBMS an, eine Aktion auszuführen; endet mit einem Semikolon CREATE TABLE People;
Klausel Clause Modifiziert eine Anweisung; kann nur innerhalb von Anweisungen auftreten WHERE, HAVING
Ausdruck Expression Liefert beim Evaluieren einen Wert zurück 6 * 7
Identifikation Identifier Name eines Datenbank-Objekts, einer Variablen oder Prozedur; kann qualifiziert oder unqualifiziert sein dbname.tablename / tablename
Prädikat Predicate Ausdruck, der zu TRUE, FALSE oder UNKNOWN evaluiert Age < 42
Abfrage Query Spezielle Anweisung; liefert Ergebnismenge von Datensätzen zurück SELECT Name FROM People WHERE Age < 42;
Funktion Function Verarbeitet einen oder mehrere Werte; erzeugt in der Regel einen neuen Wert UPPER('text') -- Gibt 'TEXT' zurück
Kommentar Comment Dient zum Kommentieren von SQL-Code; wird vom RDBMS ignoriert -- Kommentar bis zum Ende der Zeile / /*Ggf. mehrzeiliger Kommentar*/
Hinweis

SQL-Befehle wie SELECT und CREATE TABLE werden meist großgeschrieben. In der Tat unterscheidet SQL jedoch nicht zwischen Groß- und Kleinschreibung. Es handelt sich lediglich um eine weit verbreitete Konvention.

Wie lässt sich SQL-Code ausführen?

SQL-Code liegt als Quelltext in Textdateien vor. Dem Code wird erst durch eine geeignete Ausführungsumgebung Leben eingehaucht. Der Quelltext wird von einem SQL-Interpreter gelesen und in Aktionen eines RDBMS umgesetzt. Dabei gibt es zwei grundsätzliche Herangehensweisen:

  1. SQL-Code in interaktiver Sitzung ausführen

Bei diesem Ansatz wird SQL-Code direkt in ein Textfenster eingetragen oder kopiert. Der SQL-Code wird ausgeführt, das Ergebnis angezeigt. Man hat die Möglichkeit, den Code anzupassen und erneut auszuführen. Durch den die schnelle Abfolge von Code-Manipulation und Ergebnisanzeige eignet sich dieses Vorgehen am besten zum Lernen und zum Erstellen komplexer Abfragen.

  1. SQL-Code als Skript ausführen

Bei diesem Ansatz wird eine gesamte Quelltext-Datei mit SQL-Code zeilenweise ausgeführt. Dabei wird ggf. nur am Ende der Ausführung ein Feedback an den Nutzer übermittelt. Dieses Vorgehen eignet sich am besten zum Automatisieren von Abläufen und zum Einspielen von MySQL Datenbank-Backups mit MySQL-Dump.

Schnittstelle Beschreibung Beispiele
Kommandozeilen-Schnittstelle (CLI) Textbasierte Schnittstelle; SQL-Code wird eingegeben und ausgeführt, Ergebnis in Text angezeigt mysql, psql, mysqlsh
Grafische Benutzeroberfläche (GUI) SQL-Code wird in Textfenster eingegeben und/oder als Reaktion auf Nutzerinteraktion erzeugt; SQL-Code wird ausgeführt, Ergebnis in Form von Tabellen dargestellt phpMyAdmin, MySQL Workbench, HeidiSQL
Programmierschnittstelle (API) Erlaubt direkte Kommunikation mit einem RDBMS; SQL-Code wird als String in Code der jeweiligen Programmiersprache eingebunden und ausgeführt; Resultate stehen als Datenstrukturen zur weiteren Verwendung zur Verfügung PHP Data Objects (PDO), Connector/J (Java), Connector/Python, C API

Mit SQL exemplarisch eine Produktverwaltung aufbauen

Man lernt eine Programmiersprache am einfachsten, indem man selbst Code schreibt und ausführt. Wir werden im Folgenden eine Mini-Datenbank erstellen und Abfragen dagegen ausführen. Dazu nutzen wir den Online SQL interpreter der Website sql.js. Rufen Sie die verlinkte Site auf und ersetzen Sie den bereits eingetragenen SQL-Code mit dem Code aus unseren Beispielen. Führen Sie den Code Stück für Stück aus, um die Ergebnisse angezeigt zu bekommen.

Grundlegendes Vorgehen beim Aufbau einer SQL-Datenbank

Wir werden exemplarisch eine kommerzielle Produktverwaltung aufbauen, wie sie für einen physischen Laden oder einen Onlineshop zum Einsatz kommt. Dazu stecken wir grob die Anforderungen ab:

  • Es gibt eine Reihe von Produkten, von denen wir jeweils eine bestimmte Anzahl auf Lager haben.
  • Unser Kundenstamm umfasst mehrere Kunden und Kundinnen.
  • Ein Kunde oder eine Kundin gibt eine Bestellung auf, die mehrere Produkte enthalten kann.
  • Wir speichern für jede Bestellung das Bestelldatum und die bestellende Person; ferner, welche Produkte in welcher Anzahl bestellt wurden.

Diese Anforderungen übersetzen wir zunächst in eine abstrakte Beschreibung und im Anschluss in SQL-Code. Wir folgen dem nachstehenden Muster:

  1. Modell erstellen
  2. Schema definieren
  3. Datensätze einpflegen
  4. Abfragen definieren

Modell der Entitäten und Beziehungen erstellen

Der erste Schritt findet auf Papier statt bzw. nutzt spezielle Modellierungs-Tools. Wir sammeln Informationen über das zu modellierende System und abstrahieren daraus Entitäten und Relationen. Dieser Schritt wird oft als Entity Relationship (ER) Diagram verwirklicht.

Welche Entitäten gibt es und wie sind diese verknüpft? Entitäten sind Klassen von Dingen. In unserem Beispiel der Produktverwaltung finden sich die Entitäten Produkt, Kunde bzw. Kundin und Bestellung. Für jede Entität wird eine Tabelle benötigt. Auf Grund der Besonderheiten des relationalen Modells kommen weitere Tabellen hinzu, um die Relationen zu modellieren. Dies zu erkennen und gut umzusetzen, benötigt Erfahrung.

Eine zentrale Frage ist, wie die Entitäten miteinander verknüpft sind. Dabei betrachtet man beide Richtungen einer Relation und unterscheidet Singular und Plural. Am Beispiel der Beziehung Besitzer–Auto:

  1. „Einem Besitzenden gehören potenziell mehrere Autos“
  2. „Ein Auto gehört genau einem Besitzenden“

Es ergeben sich drei mögliche Beziehungsmuster zwischen zwei Entitäten:

Beziehung Entitäten Von links Von rechts
1:1-Beziehung Auto:Kennzeichen „Ein Auto hat genau ein Kennzeichen“ „Ein Kennzeichen gehört zu genau einem Auto“
1:n-Beziehung Besitzer:Auto „Einem Besitzenden gehören potenziell mehrere Autos“ „Ein Auto gehört genau einem Besitzer“
m:n-Beziehung Auto:Straße „Ein Auto fährt auf mehreren Straßen“ „Auf einer Straße fahren mehrere Autos“

Produkte implementieren

Wir implementieren zunächst die Produkte-Tabelle. Dafür definieren wir ein Schema, pflegen Datensätze ein und führen testhalber ein paar simple Abfragen aus. Wir gehen im Detail auf die einzelnen Schritte ein.

Schema definieren

Der zentrale SQL-Befehl zum Definieren von Datenbanktabellen ist CREATE TABLE. Der Befehl erzeugt eine benannte Tabelle und legt Spalten-Eigenschaften fest. Im selben Zug werden Datentypen und ggf. Einschränkungen der zu speichernden Werte definiert:

DROP TABLE IF EXISTS Products;
CREATE TABLE Products ( product_id int, product_name text, stocked int, price int );
sql
Hinweis

Wir nutzen vor der Tabellen-Definition eine DROP TABLE IF EXISTS-Anweisung. Diese entfernt eine ggf. existierende Tabelle und ermöglicht, denselben SQL-Code mehrmals auszuführen, ohne dass es zu Fehlermeldungen kommt.

Datensätze einpflegen

Wir legen ein paar Test-Datensätze an. Dabei nutzen wir den SQL-Befehl INSERT INTO sowie die VALUES-Funktion, um die Felder zu befüllen:

INSERT INTO Products VALUES (10, 'ABC Product', 74, 1050);
INSERT INTO Products VALUES (20, 'KLM Product', 23, 750);
INSERT INTO Products VALUES (30, 'XYZ Product', 104, 350);
sql

Abfragen definieren

Zum Überprüfen des Zustands der Produkte-Tabelle schreiben wir eine simple Abfrage. Wir nutzen den SELECT FROM-Befehl und geben die komplette Tabelle aus:

SELECT * FROM Products;
sql

Des Weiteren schreiben wir eine etwas komplexere Abfrage, die den Gesamtwert der gelagerten Produkte errechnet:

SELECT product_name AS 'Name', (stocked * price) AS 'Value' FROM Products;
sql

Die weiteren Tabellen implementieren

Im weiteren Verlauf legen wir die restlichen benötigten Tabellen an. Dabei gehen wir analog zur Produkte-Tabelle vor. Zunächst legen wir die Kunden-Tabelle an:

DROP TABLE IF EXISTS Customers;
CREATE TABLE Customers ( customer_id int, customer_name text, contact text );
sql

Wir pflegen Datensätze für zwei Beispiel-Kunden bzw. -Kundinnen ein:

INSERT INTO Customers VALUES (100, 'EDC Customer', 'ED@example.com');
INSERT INTO Customers VALUES (200, 'WVU Customer', 'WV@example.com');
sql

Zum Überprüfen geben wir die Kunden-Tabelle aus:

SELECT * FROM Customers;
sql

Als nächsten Schritt legen wir die Bestellungen-Tabelle an:

DROP TABLE IF EXISTS Orders;
CREATE TABLE Orders ( order_id int, customer_id int, order_date text );
sql

Wir pflegen drei Beispiel-Bestellungen ein. Beachten Sie, dass wir als ersten Wert der Datensätze eine ID als Primärschlüssel vergeben. Demgegenüber handelt es sich beim zweiten Wert um bereits existierende Kunden-IDs als Fremdschlüssel. Ferner speichern wir das Datum der Bestellung:

INSERT INTO Orders VALUES (1000, 100, '2022-05-03');
INSERT INTO Orders VALUES (1001, 100, '2022-05-04');
INSERT INTO Orders VALUES (1002, 200, '2022-05-08');
sql

Zum Testen geben wir die Bestellungen aus:

SELECT * FROM Orders;
sql

Zu guter Letzt benötigen wir eine Tabelle für die in einer Bestellung enthaltenen Produkte samt Anzahl. Es handelt sich um eine m:n-Beziehung, denn eine Bestellung kann mehrere Produkte enthalten und ein Produkt kann in mehreren Bestellungen auftauchen. Wir definieren eine Tabelle, die die IDs von Bestellungen und Produkten als Fremdschlüssel enthält:

DROP TABLE IF EXISTS OrderItems;
CREATE TABLE OrderItems ( orderitem_id int, order_id int, product_id int, count int );
sql

Wir pflegen ein paar bestellte Produkte ein. Dabei wählen wir die IDs der Bestellungen und Produkte so, dass sich eine Bestellung mit zwei Produkten sowie eine weitere Bestellung mit nur einem Produkt ergibt:

INSERT INTO OrderItems VALUES (10001, 1000, 10, 3);
INSERT INTO OrderItems VALUES (10002, 1000, 20, 2);
INSERT INTO OrderItems VALUES (10003, 1002, 30, 12);
sql

Zum Überprüfen geben wir die bestellten Produkte aus:

SELECT * FROM OrderItems;
sql

Komplexe Abfragen schreiben

Wenn Sie alle bisher gezeigten Code-Schnipsel ausgeführt haben, sollten Sie die Struktur unserer Test-Datenbank nachvollziehen können. Gehen wir nun über zu komplexeren Abfragen, an denen die Mächtigkeit von SQL deutlich wird. Schreiben wir zunächst eine Abfrage, die über mehrere Tabellen verteilte Daten zusammenführt. Wir nutzen einen SQL JOIN-Befehl, um die Daten der Kunden- und Bestellungen-Tabelle miteinander zu verknüpfen. Dabei benennen wir einige der Spalten und legen Übereinstimmung der Kunden-ID als JOIN-Bedingung fest. Beachten Sie, dass wir qualifizierte Identifikatoren verwenden, um zwischen den Spalten der beiden Tabellen zu unterscheiden:

SELECT customers.customer_name as 'Customer', customers.customer_id, orders.order_id, orders.order_date AS 'Date' FROM Customers JOIN Orders ON Orders.customer_id = Customers.customer_id ORDER BY Customers.customer_id;
sql

Zu guter Letzt nutzen wir einen weiteren JOIN-Befehl, um die Gesamtkosten der bestellten Produkte zu berechnen:

SELECT OrderItems.order_id, OrderItems.orderitem_id AS 'Order Item', Products.product_name AS 'Product', Products.price AS 'Unit Price', OrderItems.count AS 'Count', (OrderItems.count * Products.price) AS 'Total' FROM OrderItems JOIN Products ON OrderItems.product_id = Products.product_id;
sql
Tipp

Wenn Sie mehr darüber erfahren möchten, was genau SQL ist, Hilfe bei spezifischen Problemen mit der Datenbanksprache benötigen oder einfach nur Wissen erweitern wollen, helfen Ihnen unsere Digital-Guide-Artikel weiter: