Daten Abfragen
Im Thema Datenmodelierung haben wir gelernt, auf was beim planen und gestalten einer Datenbank geachtet werden muss. Wir können leider nur einen Bruchteil der "echten Welt" betrachten. In der Realität müssen auch noch Dinge wie z.B.:
- Erweiterbarkeit: Ist die Datenbank so geplant, dass sie möglichst einfach erweitert werden kann
- Performanz: Kann man irgendwo noch etwas mehr Geschwindigkeit herausholen?
- Sicherheit: Wie bestimmen wir, wer auf welche Daten zugreifen darf?
Für den Moment haben wir aber einmal genug geplant und geben uns mit unseren Tabellen mit Primärschlüsseln, Fremdschlüsseln und Beziehungen zufrieden.
In den folgenden Abschnitten geht es nun darum, wie wir Daten aus einer DAtenbank abfragen können. Wir gehen also hier immer von einer bestehenden Datenbank (inkl. Daten) aus.
Structured Query Language - SQL
Die Structured Query Language, oder eben kurz SQL, wurde um 1970 bei IBM entwickelt, nachdem das Paper von Cobb (siehe Datenmodelierung) gelesen wurde. Seit damals hat sie viele Änderungen mitgemacht und sich dabei zum Standard entwickelt. Das bedeutet, dass heute die allermeisten Datenbanken über SQL-Code abgefragt werden.
SQL Abfragen
SQL unterscheidet sich stark von normalen Programmiersprachen. Es gibt keinen Ablauf, wie z.B. bei Python. Mach spricht auch nicht von Programmen, sondern von Abfragen. Du kannst dir jedes Stück SQL-Code wie eine Auswahl an Daten vorstellen, die von der Datenbank bekommen möchtest.
Um immer mit Beispielen arbeiten zu können werden wir für die kommenden Script-Teile mit einer Kunden-Tabelle ähnlich zu der Tabelle aus
Strickotopia.
Tabelle: kunden
| Vorname | Name | Strasse | PLZ | Land | |
|---|---|---|---|---|---|
| Max | Mustermann | max.muster@gmx.ch | Kirchgasse 12 | 6020 | Schweiz |
| Anna | Schmidt | anna.schmidt@schule.ch | Hauptstraße 5 | 8010 | Schweiz |
| Lukas | Weber | lukas.weber@weber.de | Bahnhofstr. 23 | 6900 | Deutschland |
| Sophie | Müller | sophie.mueller@schule.at | Schillerweg 8 | 4020 | Österreich |
| Jonas | Fischer | jonas.fischer@schule.ch | Rosenweg 15 | 5020 | Schweiz |
SELECT
Die einfachste SQL Abfrage, die es gibt sieht folgendermassen aus:
SELECT * FROM kunden;Hinweis
Das Asterisk Zeichen * steht in der Informatik häufig für alles. Du kannst es in SQL-Abfragen also durch das Wort all/alles ersetzen.
Die Abfrage bedeutet also wörtlich: Wähle alles aus kunden. Sie wird dir sämtliche Zeilen und Spalten aus der Kundentabelle liefern. Mit 4 Wörtern können wir also schon eine Tabelle auslesen - ziemlich easy!
📊 Strickotopia Datenbank
Tabellen anzeigen
id (PK), vorname, name, email, strasse, plz, landid (PK), name, preis, stoff, stoffmengeid (PK), kunde (FK→kunden.id), datumbestellung (FK→bestellungen.id), produkt (FK→produkte.id), mengeNun will man aber normalerweise nicht alle Informationen aus einer Tabelle. Oft ist man nur an gewissen Einträgen (Zeilen, z.B. bestimmter Kunde) und gewissen Spalten (z.B. E-Mail) interessiert. Man sollte immer nur das abfragen, was man tatsächlich benötigt um die Abfrage und das versenden der Daten möglichst effizient zu halten.
Hinweis
Denk daran, die Datenbank einer Anwendung steht oft auf der anderen Seite der Erde. Alle Daten, die für nichts versendet werden generieren unnötigen Datenverkehr und somit Kosten.
Die erste logische Einschränkung ist es also, den * zu ersetzen:
SELECT email, strasse from kunden;Auch diese Abfrage lässt sich einfach "eindeutschen": Wähle email und strasse aus kunden. Teste die Abfrage in Ruhe aus um dich zu vergewissern, was sie macht.
WHERE
Nun haben wir die Möglichkeit, nur bestimmte Spalten auszuwählen. Der nächste logische Schritt ist es, auch bei den Einträgen/Zeilen genauer sagen zu können, was wir wollen. Da die meisten Datenbanken hunderttausende von Einträgen haben ist eine Abfrage auf alle Zeilen nicht sehr hilfreich.
Hier kommt das Schlüsselwort WHEREins Spiel. Ein Beispiel:
SELECT email from kunden
WHERE land = 'Schweiz';Frage
Wie würdest du diese Abfrage eindeutschen? Überlege es dir kurz und schaue danach die Antwort an.
Antwort
Wähle email aller kunden mit dem Land 'Schweiz'
Und somit kennst du auch schon die allerwichtigsten Elemente einer SQL-Abfrage:
- SELECT -> Welche Spalten
- FROM -> Welche Tabelle
- WHERE -> Welche Zeilen
SQL erlaubt jedoch noch viele andere Arten von Einschränkungen im WHERE Teil:
Ist Wert in einer Liste von Werten?
SELECT email FROM kunden
WHERE land in ('Schweiz', 'Deutschland');Ist eine Zahl zwischen zwei Werten?
SELECT name FROM produkte
WHERE PREIS BETWEEN 5 AND 15;Logische UND Verknüpfung
SELECT name FROM produkte
WHERE preis < 10 AND STOFFMENGE < 10;Logische ODER Verknüpfung
SELECT name FROM produkte
WHERE preis > 10 OR stoff = 'Papier';Resultate Sortieren
Bisher haben wir gelernt, wie wir Spalten auswählen und Zeilen filtern können. Aber was, wenn wir die Ergebnisse in einer bestimmten Reihenfolge brauchen? Zum Beispiel die teuersten Produkte zuerst, oder die größten Länder?
Hier kommt ORDER BY ins Spiel:
SELECT name, population FROM world
ORDER BY population DESC;Hinweis
DESC steht für descending (absteigend). Für aufsteigend kannst du ASC schreiben oder es einfach weglassen - das ist der Standard.
Probier es aus:
🌍 SQLzoo World Datenbank
Tabellen anzeigen
name (PK), continent, area, population, gdpid (PK), name, country, populationHier siehst du auch gleich einen neuen Befehl: LIMIT. Damit kannst du die Anzahl der Ergebnisse begrenzen - sehr nützlich wenn du nur die Top-5 oder Top-10 haben möchtest.
Zusammenfassende Funktionen
Oft interessiert uns nicht jede einzelne Zeile, sondern eine Zusammenfassung. Zum Beispiel:
- Wie viele Länder gibt es?
- Was ist die durchschnittliche Bevölkerung?
- Welches ist das reichste Land?
Dafür gibt es Zusammenfassend Funktionen:
| Funktion | Bedeutung | Beispiel |
|---|---|---|
COUNT(*) | Anzahl Zeilen | SELECT COUNT(*) FROM world; |
SUM(salary) | Summe | SELECT SUM(population) FROM world; |
AVG(price) | Durchschnitt | SELECT AVG(gdp) FROM world; |
MAX(population) | Maximum | SELECT MAX(population) FROM world; |
MIN(area) | Minimum | SELECT MIN(area) FROM world; |
🌍 SQLzoo World Datenbank
Tabellen anzeigen
name (PK), continent, area, population, gdpid (PK), name, country, populationHinweis
AS gibt der Ergebnisspalte einen neuen Namen - das ist besonders bei komplexeren Abfragen sehr hilfreich!
GROUP BY - Gruppieren
Wir können Daten nicht nur zusammenfassen, sondern auch gruppiert zusammenfassen. Zum Beispiel: Wie viele Länder gibt es pro Kontinent?
SELECT continent, COUNT(*) AS anzahl
FROM world
GROUP BY continent;🌍 SQLzoo World Datenbank
Tabellen anzeigen
name (PK), continent, area, population, gdpid (PK), name, country, populationHier passiert folgendes:
GROUP BY continent- Teile die Daten nach Kontinenten aufCOUNT(*)undAVG(population)werden für jede Gruppe separat berechnet
Join - Tabellen verknüpfen
Bisher haben wir immer nur mit einer einzelnen Tabelle gearbeitet. In der echten Welt sind Daten aber fast immer auf mehrere Tabellen aufgeteilt. Das nennt man Normalisierung (hattest du beim Thema Datenmodellierung).
In der Abfrage kann es aber nun sein, dass wir die Daten aus den einzelnen Tabellen kombiniert haben möchten. Zum Beispiel Alle Bestellungen eines Kunden, inkl. Name & E-Mail des Kunden. Mit unseren bisherigen Kentnissen ist das nicht in einer Abfrage möglich.
Mit dem JOIN Befehl können wir 2 Tabellen verknüpfen. Wir müssen der Datenbank mit dem ON sagen, wie es die Zeilen matchen soll:
SELECT city.name, city.population, world.continent
FROM city
JOIN world ON city.country = world.name;Was passiert hier?
FROM city- Starte mit der TabellecityJOIN world- Verbinde die TabelleworldON city.country = world.name- Verbinde über die Spaltecountry(in city) mitname(in world)
📊 Strickotopia Datenbank
Tabellen anzeigen
id (PK), vorname, name, email, strasse, plz, landid (PK), name, preis, stoff, stoffmengeid (PK), kunde (FK→kunden.id), datumbestellung (FK→bestellungen.id), produkt (FK→produkte.id), mengeNeue Werte hinzufügen
Unser kleiner Exkurs in die SQL Sprache endet mit einem wichtigen Element: Neue Werte hinzufügen. Datenbanken werden laufend erweitert. Neue Kund:innen, neue Bestellungen, usw.
Dafür wird eine anderer Grund-Befehl verwendet. SELECT (also wähle) passt hier nicht. In der Praxis sieht das so aus:
INSERT - Daten hinzufügen
INSERT INTO kunden (vorname, name, email, strasse, plz, land)
VALUES ('Maria', 'Huber', 'maria.huber@email.at', 'Dorfplatz 1', '6900', 'Österreich');Was passiert hier?
INSERT INTO kunden- In welche Tabelle?(spalten...)- Welche Spalten werden befüllt?VALUES (werte...)- Die tatsächlichen Daten
Hinweis
Der Primärschlüssel (id) wird oft automatisch vergeben - darum musst du ihn nicht angeben!
📊 Strickotopia Datenbank
Tabellen anzeigen
id (PK), vorname, name, email, strasse, plz, landid (PK), name, preis, stoff, stoffmengeid (PK), kunde (FK→kunden.id), datumbestellung (FK→bestellungen.id), produkt (FK→produkte.id), menge