Die Syntax der Pro­gram­mier­spra­che SQL baut auf der re­la­tio­na­len Algebra auf und un­ter­schei­det sich daher auf viel­fäl­ti­ge Weise von anderen Pro­gram­mier­spra­chen. Um SQL zu lernen, sind Kennt­nis­se über diese Syntax sowie an­schau­li­che Beispiele äußerst hilfreich.

Grund­la­gen der SQL-Syntax

Generell versteht man unter Syntax die „Schreib­wei­se“ einer Pro­gram­mier­spra­che. Die Syntax legt fest, welche Arten von grund­le­gen­den Code-Kon­struk­ten es gibt und wie sich diese mit­ein­an­der ver­knüp­fen lassen. Das Ver­ständ­nis der Syntax ist eine grund­sätz­li­che Vor­aus­set­zung zum Lesen und Schreiben von Code in der je­wei­li­gen Sprache.

Die wich­tigs­ten Syntax-Kon­struk­te in SQL sind SQL-An­wei­sun­gen mit ggf. darin ent­hal­te­nen Klauseln. Obwohl technisch nicht ganz korrekt, werden beide im All­ge­mei­nen als „SQL-Befehle“ be­zeich­net. Daneben exis­tie­ren weitere Syntax-Kon­struk­te, die wir der Übersicht halber dar­stel­len:

Begriff Englische Ent­spre­chung Erklärung Beispiel
Anweisung Statement Weist das DBMS an, eine Aktion aus­zu­füh­ren; endet mit einem Semikolon CREATE TABLE People;
Klausel Clause Mo­di­fi­ziert eine Anweisung; kann nur innerhalb von An­wei­sun­gen auftreten WHERE, HAVING
Ausdruck Ex­pres­si­on Liefert beim Eva­lu­ie­ren einen Wert zurück 6 * 7
Iden­ti­fi­ka­ti­on Iden­ti­fier Name eines Datenbank-Objekts, einer Variablen oder Prozedur; kann qua­li­fi­ziert oder un­qua­li­fi­ziert sein dbname.tablename / tablename
Prädikat Predicate Ausdruck, der zu TRUE, FALSE oder UNKNOWN evaluiert Age < 42
Abfrage Query Spezielle Anweisung; liefert Er­geb­nis­men­ge von Da­ten­sät­zen zurück SELECT Name FROM People WHERE Age < 42;
Funktion Function Ver­ar­bei­tet einen oder mehrere Werte; erzeugt in der Regel einen neuen Wert UPPER('text') -- Gibt 'TEXT' zurück
Kommentar Comment Dient zum Kom­men­tie­ren 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ß­ge­schrie­ben. In der Tat un­ter­schei­det SQL jedoch nicht zwischen Groß- und Klein­schrei­bung. Es handelt sich lediglich um eine weit ver­brei­te­te Kon­ven­ti­on.

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

SQL-Code liegt als Quelltext in Text­da­tei­en vor. Dem Code wird erst durch eine geeignete Aus­füh­rungs­um­ge­bung Leben ein­ge­haucht. Der Quelltext wird von einem SQL-In­ter­pre­ter gelesen und in Aktionen eines RDBMS umgesetzt. Dabei gibt es zwei grund­sätz­li­che Her­an­ge­hens­wei­sen:

  1. SQL-Code in in­ter­ak­ti­ver Sitzung ausführen

Bei diesem Ansatz wird SQL-Code direkt in ein Text­fens­ter ein­ge­tra­gen oder kopiert. Der SQL-Code wird aus­ge­führt, das Ergebnis angezeigt. Man hat die Mög­lich­keit, den Code an­zu­pas­sen und erneut aus­zu­füh­ren. Durch den die schnelle Abfolge von Code-Ma­ni­pu­la­ti­on und Er­geb­nisan­zei­ge 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 zei­len­wei­se aus­ge­führt. Dabei wird ggf. nur am Ende der Aus­füh­rung ein Feedback an den Nutzer über­mit­telt. Dieses Vorgehen eignet sich am besten zum Au­to­ma­ti­sie­ren von Abläufen und zum Ein­spie­len von MySQL Datenbank-Backups mit MySQL-Dump.

Schnitt­stel­le Be­schrei­bung Beispiele
Kom­man­do­zei­len-Schnitt­stel­le (CLI) Text­ba­sier­te Schnitt­stel­le; SQL-Code wird ein­ge­ge­ben und aus­ge­führt, Ergebnis in Text angezeigt mysql, psql, mysqlsh
Grafische Be­nut­zer­ober­flä­che (GUI) SQL-Code wird in Text­fens­ter ein­ge­ge­ben und/oder als Reaktion auf Nut­zer­inter­ak­ti­on erzeugt; SQL-Code wird aus­ge­führt, Ergebnis in Form von Tabellen dar­ge­stellt phpMy­Ad­min, MySQL Workbench, HeidiSQL
Pro­gram­mier­schnitt­stel­le (API) Erlaubt direkte Kom­mu­ni­ka­ti­on mit einem RDBMS; SQL-Code wird als String in Code der je­wei­li­gen Pro­gram­mier­spra­che ein­ge­bun­den und aus­ge­führt; Resultate stehen als Da­ten­struk­tu­ren zur weiteren Ver­wen­dung zur Verfügung PHP Data Objects (PDO), Connector/J (Java), Connector/Python, C API

Mit SQL ex­em­pla­risch eine Pro­dukt­ver­wal­tung aufbauen

Man lernt eine Pro­gram­mier­spra­che am ein­fachs­ten, 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 in­ter­pre­ter der Website sql.js. Rufen Sie die verlinkte Site auf und ersetzen Sie den bereits ein­ge­tra­ge­nen SQL-Code mit dem Code aus unseren Bei­spie­len. Führen Sie den Code Stück für Stück aus, um die Er­geb­nis­se angezeigt zu bekommen.

Grund­le­gen­des Vorgehen beim Aufbau einer SQL-Datenbank

Wir werden ex­em­pla­risch eine kom­mer­zi­el­le Pro­dukt­ver­wal­tung aufbauen, wie sie für einen phy­si­schen Laden oder einen On­line­shop zum Einsatz kommt. Dazu stecken wir grob die An­for­de­run­gen ab:

  • Es gibt eine Reihe von Produkten, von denen wir jeweils eine bestimmte Anzahl auf Lager haben.
  • Unser Kun­den­stamm umfasst mehrere Kunden und Kundinnen.
  • Ein Kunde oder eine Kundin gibt eine Be­stel­lung auf, die mehrere Produkte enthalten kann.
  • Wir speichern für jede Be­stel­lung das Be­stell­da­tum und die be­stel­len­de Person; ferner, welche Produkte in welcher Anzahl bestellt wurden.

Diese An­for­de­run­gen über­set­zen wir zunächst in eine abstrakte Be­schrei­bung und im Anschluss in SQL-Code. Wir folgen dem nach­ste­hen­den Muster:

  1. Modell erstellen
  2. Schema de­fi­nie­ren
  3. Da­ten­sät­ze ein­pfle­gen
  4. Abfragen de­fi­nie­ren

Modell der Entitäten und Be­zie­hun­gen erstellen

Der erste Schritt findet auf Papier statt bzw. nutzt spezielle Mo­del­lie­rungs-Tools. Wir sammeln In­for­ma­tio­nen über das zu mo­del­lie­ren­de System und abs­tra­hie­ren daraus Entitäten und Re­la­tio­nen. Dieser Schritt wird oft als Entity Re­la­ti­onship (ER) Diagram ver­wirk­licht.

Welche Entitäten gibt es und wie sind diese verknüpft? Entitäten sind Klassen von Dingen. In unserem Beispiel der Pro­dukt­ver­wal­tung finden sich die Entitäten Produkt, Kunde bzw. Kundin und Be­stel­lung. Für jede Entität wird eine Tabelle benötigt. Auf Grund der Be­son­der­hei­ten des re­la­tio­na­len Modells kommen weitere Tabellen hinzu, um die Re­la­tio­nen zu mo­del­lie­ren. Dies zu erkennen und gut um­zu­set­zen, benötigt Erfahrung.

Eine zentrale Frage ist, wie die Entitäten mit­ein­an­der verknüpft sind. Dabei be­trach­tet man beide Rich­tun­gen einer Relation und un­ter­schei­det Singular und Plural. Am Beispiel der Beziehung Besitzer–Auto:

  1. „Einem Be­sit­zen­den gehören po­ten­zi­ell mehrere Autos“
  2. „Ein Auto gehört genau einem Be­sit­zen­den“

Es ergeben sich drei mögliche Be­zie­hungs­mus­ter zwischen zwei Entitäten:

Beziehung Entitäten Von links Von rechts
1:1-Beziehung Auto:Kenn­zei­chen „Ein Auto hat genau ein Kenn­zei­chen“ „Ein Kenn­zei­chen gehört zu genau einem Auto“
1:n-Beziehung Besitzer:Auto „Einem Be­sit­zen­den gehören po­ten­zi­ell 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 im­ple­men­tie­ren

Wir im­ple­men­tie­ren zunächst die Produkte-Tabelle. Dafür de­fi­nie­ren wir ein Schema, pflegen Da­ten­sät­ze ein und führen test­hal­ber ein paar simple Abfragen aus. Wir gehen im Detail auf die einzelnen Schritte ein.

Schema de­fi­nie­ren

Der zentrale SQL-Befehl zum De­fi­nie­ren von Da­ten­bank­ta­bel­len ist CREATE TABLE. Der Befehl erzeugt eine benannte Tabelle und legt Spalten-Ei­gen­schaf­ten fest. Im selben Zug werden Da­ten­ty­pen und ggf. Ein­schrän­kun­gen der zu spei­chern­den 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-De­fi­ni­ti­on eine DROP TABLE IF EXISTS-Anweisung. Diese entfernt eine ggf. exis­tie­ren­de Tabelle und er­mög­licht, denselben SQL-Code mehrmals aus­zu­füh­ren, ohne dass es zu Feh­ler­mel­dun­gen kommt.

Da­ten­sät­ze ein­pfle­gen

Wir legen ein paar Test-Da­ten­sät­ze 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 de­fi­nie­ren

Zum Über­prü­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 kom­ple­xe­re Abfrage, die den Ge­samt­wert der ge­la­ger­ten Produkte errechnet:

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

Die weiteren Tabellen im­ple­men­tie­ren

Im weiteren Verlauf legen wir die rest­li­chen be­nö­tig­ten 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 Da­ten­sät­ze 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 Über­prü­fen geben wir die Kunden-Tabelle aus:

SELECT * FROM Customers;
sql

Als nächsten Schritt legen wir die Be­stel­lun­gen-Tabelle an:

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

Wir pflegen drei Beispiel-Be­stel­lun­gen ein. Beachten Sie, dass wir als ersten Wert der Da­ten­sät­ze eine ID als Pri­mär­schlüs­sel vergeben. Dem­ge­gen­über handelt es sich beim zweiten Wert um bereits exis­tie­ren­de Kunden-IDs als Fremd­schlüs­sel. Ferner speichern wir das Datum der Be­stel­lung:

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 Be­stel­lun­gen aus:

SELECT * FROM Orders;
sql

Zu guter Letzt benötigen wir eine Tabelle für die in einer Be­stel­lung ent­hal­te­nen Produkte samt Anzahl. Es handelt sich um eine m:n-Beziehung, denn eine Be­stel­lung kann mehrere Produkte enthalten und ein Produkt kann in mehreren Be­stel­lun­gen auf­tau­chen. Wir de­fi­nie­ren eine Tabelle, die die IDs von Be­stel­lun­gen und Produkten als Fremd­schlüs­sel 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 Be­stel­lun­gen und Produkte so, dass sich eine Be­stel­lung mit zwei Produkten sowie eine weitere Be­stel­lung 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 Über­prü­fen geben wir die be­stell­ten Produkte aus:

SELECT * FROM OrderItems;
sql

Komplexe Abfragen schreiben

Wenn Sie alle bisher gezeigten Code-Schnipsel aus­ge­führt haben, sollten Sie die Struktur unserer Test-Datenbank nach­voll­zie­hen können. Gehen wir nun über zu kom­ple­xe­ren Abfragen, an denen die Mäch­tig­keit von SQL deutlich wird. Schreiben wir zunächst eine Abfrage, die über mehrere Tabellen verteilte Daten zu­sam­men­führt. Wir nutzen einen SQL JOIN-Befehl, um die Daten der Kunden- und Be­stel­lun­gen-Tabelle mit­ein­an­der zu ver­knüp­fen. Dabei benennen wir einige der Spalten und legen Über­ein­stim­mung der Kunden-ID als JOIN-Bedingung fest. Beachten Sie, dass wir qua­li­fi­zier­te Iden­ti­fi­ka­to­ren verwenden, um zwischen den Spalten der beiden Tabellen zu un­ter­schei­den:

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 Ge­samt­kos­ten der be­stell­ten 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 spe­zi­fi­schen Problemen mit der Da­ten­bank­spra­che benötigen oder einfach nur Wissen erweitern wollen, helfen Ihnen unsere Digital-Guide-Artikel weiter:

Zum Hauptmenü