Skip to content

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

VornameNameE-MailStrassePLZLand
MaxMustermannmax.muster@gmx.chKirchgasse 126020Schweiz
AnnaSchmidtanna.schmidt@schule.chHauptstraße 58010Schweiz
LukasWeberlukas.weber@weber.deBahnhofstr. 236900Deutschland
SophieMüllersophie.mueller@schule.atSchillerweg 84020Österreich
JonasFischerjonas.fischer@schule.chRosenweg 155020Schweiz

SELECT

Die einfachste SQL Abfrage, die es gibt sieht folgendermassen aus:

SQL
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
kundenid (PK), vorname, name, email, strasse, plz, land
produkteid (PK), name, preis, stoff, stoffmenge
bestellungenid (PK), kunde (FK→kunden.id), datum
bestellpositionenbestellung (FK→bestellungen.id), produkt (FK→produkte.id), menge

Nun 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:

SQL
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:

SQL
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?

SQL
SELECT email FROM kunden
WHERE land in ('Schweiz', 'Deutschland');

Ist eine Zahl zwischen zwei Werten?

SQL
SELECT name FROM produkte
WHERE PREIS BETWEEN 5 AND 15;

Logische UND Verknüpfung

SQL
SELECT name FROM produkte
WHERE preis < 10 AND STOFFMENGE < 10;

Logische ODER Verknüpfung

SQL
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:

SQL
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
worldname (PK), continent, area, population, gdp
cityid (PK), name, country, population

Hier 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:

FunktionBedeutungBeispiel
COUNT(*)Anzahl ZeilenSELECT COUNT(*) FROM world;
SUM(salary)SummeSELECT SUM(population) FROM world;
AVG(price)DurchschnittSELECT AVG(gdp) FROM world;
MAX(population)MaximumSELECT MAX(population) FROM world;
MIN(area)MinimumSELECT MIN(area) FROM world;

🌍 SQLzoo World Datenbank

Tabellen anzeigen
worldname (PK), continent, area, population, gdp
cityid (PK), name, country, population

Hinweis

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?

SQL
SELECT continent, COUNT(*) AS anzahl
FROM world
GROUP BY continent;

🌍 SQLzoo World Datenbank

Tabellen anzeigen
worldname (PK), continent, area, population, gdp
cityid (PK), name, country, population

Hier passiert folgendes:

  1. GROUP BY continent - Teile die Daten nach Kontinenten auf
  2. COUNT(*) und AVG(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:

SQL
SELECT city.name, city.population, world.continent
FROM city
JOIN world ON city.country = world.name;

Was passiert hier?

  1. FROM city - Starte mit der Tabelle city
  2. JOIN world - Verbinde die Tabelle world
  3. ON city.country = world.name - Verbinde über die Spalte country (in city) mit name (in world)

📊 Strickotopia Datenbank

Tabellen anzeigen
kundenid (PK), vorname, name, email, strasse, plz, land
produkteid (PK), name, preis, stoff, stoffmenge
bestellungenid (PK), kunde (FK→kunden.id), datum
bestellpositionenbestellung (FK→bestellungen.id), produkt (FK→produkte.id), menge

Neue 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

SQL
INSERT INTO kunden (vorname, name, email, strasse, plz, land)
VALUES ('Maria', 'Huber', 'maria.huber@email.at', 'Dorfplatz 1', '6900', 'Österreich');

Was passiert hier?

  1. INSERT INTO kunden - In welche Tabelle?
  2. (spalten...) - Welche Spalten werden befüllt?
  3. 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
kundenid (PK), vorname, name, email, strasse, plz, land
produkteid (PK), name, preis, stoff, stoffmenge
bestellungenid (PK), kunde (FK→kunden.id), datum
bestellpositionenbestellung (FK→bestellungen.id), produkt (FK→produkte.id), menge

Quellen

Informatik & ICT Unterricht Neufeld