Tutorial: Einstieg in Microsoft SQL mit der Beispieldatenbank „Standard“
Ein praxisnahes Tutorial mit vielen Beispielen aus den Tabellen Lieferant, Artikel und Lieferung.
1) Einführung in SQL
SQL (Structured Query Language) ist die Standardsprache, um Daten in relationalen
Datenbanken zu speichern, zu ändern, zu löschen und abzufragen.
„Relational“ bedeutet, dass Daten in Tabellen organisiert sind, die über Schlüssel miteinander verbunden werden.
2) Die Beispieldatenbank „Standard“
Wir arbeiten mit drei Tabellen:
- Lieferant (LNr, LName, Status, LStadt)
- Artikel (ANr, AName, Farbe, Gewicht, AStadt, AMenge)
- Lieferung (LNr, ANr, LMenge, LDatum)
Die Tabellen sind über die Nummern LNr
(Lieferant) und ANr
(Artikel) logisch verknüpft.
3) Erste SQL-Befehle (SELECT & WHERE)
SELECT
-- aktuelles Datum (SQL Server)
SELECT GETDATE();
-- alle Spalten aus einer Tabelle
SELECT * FROM lieferant;
-- nur bestimmte Spalten
SELECT aname FROM artikel;
WHERE
-- Alle Lieferanten aus Hamburg
SELECT *
FROM lieferant
WHERE LStadt = 'Hamburg';
-- Alle roten Artikel
SELECT *
FROM artikel
WHERE farbe = 'rot';
-- Lieferungen am 09.08.1990
SELECT *
FROM lieferung
WHERE LDatum = '1990-08-09'; -- ISO-Format in T-SQL empfohlen
4) Wichtige Operatoren: BETWEEN, IN, LIKE
BETWEEN
-- Lieferungen im August 1990
SELECT *
FROM lieferung
WHERE LDatum BETWEEN '1990-08-01' AND '1990-08-31';
IN
-- Lieferungen mit 100, 300 oder 400 Stück
SELECT *
FROM lieferung
WHERE LMenge IN (100, 300, 400);
-- rote ODER blaue Artikel
SELECT *
FROM artikel
WHERE farbe IN ('rot', 'blau');
LIKE
-- Lieferanten, deren Name mit B oder J beginnt
SELECT *
FROM lieferant
WHERE LName LIKE 'B%' OR LName LIKE 'J%';
-- Artikel, deren Name an 2. Stelle ein 'o' hat
SELECT *
FROM artikel
WHERE AName LIKE '_o%';
5) Duplikate vermeiden: DISTINCT
-- alle verschiedenen Lieferantennummern aus Lieferung
SELECT DISTINCT LNr
FROM lieferung;
6) Sortieren mit ORDER BY
-- Artikel alphabetisch absteigend
SELECT AName, Farbe, AStadt
FROM artikel
ORDER BY AName DESC;
7) Ergebnisse eingrenzen mit TOP n
-- die drei größten Liefermengen
SELECT TOP (3) LNr, LMenge, LDatum
FROM lieferung
ORDER BY LMenge DESC;
8) Bedingte Ausgaben mit CASE
SELECT ANr, AName, AMenge,
CASE
WHEN AMenge BETWEEN 0 AND 400 THEN 'nachbestellen'
WHEN AMenge BETWEEN 401 AND 1000 THEN 'ausreichend'
ELSE 'Lager voll'
END AS Bewertung
FROM artikel;
9) Aggregatfunktionen & GROUP BY
COUNT()
– AnzahlSUM()
– SummeAVG()
– DurchschnittMIN()
/MAX()
– kleinster/größter Wert
-- kleinste Liefermenge je Lieferant
SELECT LNr, MIN(LMenge) AS Mindestliefermenge
FROM lieferung
GROUP BY LNr;
-- Summe gelagerter Artikel pro Farbe
SELECT Farbe, SUM(AMenge) AS Gesamtbestand
FROM artikel
GROUP BY Farbe;
10) HAVING – Bedingungen für Gruppen
-- nur Lieferanten mit durchschnittlicher Liefermenge >= 250
SELECT LNr, AVG(LMenge) AS Durchschnitt
FROM lieferung
GROUP BY LNr
HAVING AVG(LMenge) >= 250;
11) Unterabfragen (Subqueries)
-- Lieferanten mit Status über dem Gesamt-Durchschnitt
SELECT *
FROM lieferant
WHERE Status > (SELECT AVG(Status) FROM lieferant);
-- Artikel (Nr, Name, Ort), die am 23.07.1990 ausgeliefert wurden
SELECT ANr, AName, AStadt
FROM artikel
WHERE ANr IN (
SELECT ANr
FROM lieferung
WHERE LDatum = '1990-07-23'
);
12) ANY, ALL & EXISTS
-- schwerer als alle Artikel in Ludwigshafen
SELECT *
FROM artikel
WHERE Gewicht > ALL (SELECT Gewicht FROM artikel WHERE AStadt = 'Ludwigshafen');
-- Lieferanten, die bereits geliefert haben (EXISTS, korreliert)
SELECT *
FROM lieferant a
WHERE EXISTS (
SELECT 1
FROM lieferung b
WHERE b.LNr = a.LNr
);
13) Datums- & Zeitfunktionen
-- aktuelles Datum/Zeit
SELECT GETDATE(); -- lokal
SELECT GETUTCDATE(); -- UTC
-- Zahlungsziel: 35 Tage nach Lieferdatum
SELECT ANr, LDatum, DATEADD(day, 35, LDatum) AS Zahlungsziel
FROM lieferung;
-- Lieferungen aus Juli 1990 (DATEPART)
SELECT *
FROM lieferung
WHERE DATEPART(year, LDatum) = 1990
AND DATEPART(month, LDatum) = 7;
-- Ausgabe im deutschen Format (104)
SELECT LNr, ANr, LDatum, CONVERT(char(10), LDatum, 104) AS LDatum_DE
FROM lieferung
WHERE DATEPART(year, LDatum) = 1990
AND DATEPART(month, LDatum) = 7;
Tipp: Für Vergleiche nutze ISO-Datum (YYYY-MM-DD
), um Missverständnisse zu vermeiden.
14) Daten einfügen, ändern, löschen (INSERT/UPDATE/DELETE)
-- Einfügen (alle Spalten in Tabellenspaltenreihenfolge)
INSERT INTO lieferant VALUES ('L07', 'Hustensaftschmuggler', 20, 'Erfurt');
-- Einfügen (Spalten explizit angeben, Reihenfolge egal)
INSERT INTO lieferant (LStadt, LNr, LName, Status)
VALUES ('Weimar', 'L08', 'Conny', 10);
-- Unbekannte Werte (NULL)
INSERT INTO lieferant (LNr, LName, Status, LStadt)
VALUES ('L09', 'Okupenko', 10, NULL);
-- Ändern
UPDATE lieferant
SET Status = 20
WHERE LName = 'Okupenko';
-- Löschen
DELETE FROM lieferant
WHERE LNr = 'L10';
15) Tabellen verknüpfen mit JOIN
INNER JOIN
-- Lieferant + Lieferung
SELECT *
FROM lieferant a
JOIN lieferung b ON a.LNr = b.LNr;
-- Lieferant + Lieferung + Artikel
SELECT a.LName, c.AName, b.LMenge, b.LDatum
FROM lieferant a
JOIN lieferung b ON a.LNr = b.LNr
JOIN artikel c ON b.ANr = c.ANr;
LEFT/RIGHT/FULL OUTER JOIN
-- alle Lieferanten inkl. derer ohne Lieferung
SELECT a.*, b.ANr, b.LMenge, b.LDatum
FROM lieferant a
LEFT JOIN lieferung b ON a.LNr = b.LNr;
-- alle Lieferungen inkl. verwaister Einträge
SELECT a.*, b.LName, b.LStadt
FROM lieferung a
RIGHT JOIN lieferant b ON a.LNr = b.LNr;
-- alle Datensätze beider Seiten
SELECT *
FROM lieferant a
FULL OUTER JOIN lieferung b ON a.LNr = b.LNr;
16) Übungsaufgaben
- Liste alle Lieferanten in Hamburg mit
Status > 10
. - Finde alle Artikel, deren
Gewicht
zwischen14
und17
liegt. - Ermittle Namen der Lieferanten, die den Artikel
A05
geliefert haben. - Gib die Gesamtlagerbestände pro Farbe aus.
- Zeige die Top 3 Lieferungen nach Menge.
- Erstelle eine Abfrage, die Lieferungen vom
1990-08-05
oder1990-08-06
findet – einmal mitIN
, einmal mitBETWEEN
.
Musterlösungen (aufklappen)
-- 1
SELECT *
FROM lieferant
WHERE LStadt = 'Hamburg' AND Status > 10;
-- 2
SELECT *
FROM artikel
WHERE Gewicht BETWEEN 14 AND 17;
-- 3
SELECT DISTINCT a.LName
FROM lieferant a
JOIN lieferung b ON a.LNr = b.LNr
WHERE b.ANr = 'A05';
-- 4
SELECT Farbe, SUM(AMenge) AS Gesamtbestand
FROM artikel
GROUP BY Farbe;
-- 5
SELECT TOP (3) LNr, LMenge, LDatum
FROM lieferung
ORDER BY LMenge DESC;
-- 6 (Variante IN)
SELECT *
FROM lieferung
WHERE LDatum IN ('1990-08-05','1990-08-06');
-- 6 (Variante BETWEEN)
SELECT *
FROM lieferung
WHERE LDatum BETWEEN '1990-08-05' AND '1990-08-06';
