Tabellen-Aliase
In einem Join kommen die Namen der Tabellen immer wieder vor: in ON und vor jeder Spalte, die beide Tabellen haben. Die Abfragen werden lang. Darum kannst du einer Tabelle direkt hinter ihrem Namen in FROM oder JOIN einen kurzen Namen geben, einen Alias. Das ist die Abfrage aus der vorigen Übung, mit Aliasen:
SELECT s.titel, bw.sterne, bw.kommentar
FROM bewertungen AS bw
JOIN spiele AS s ON bw.spiel_id = s.id
ORDER BY s.titel, bw.kunde_id;| titel | sterne | kommentar |
|---|---|---|
| Bakery Story | 4 | Niedlich und beruhigend. |
| Cube Logic | 3 | NULL |
| Cube Logic | 5 | Perfekt für den Bus. |
| … | … | … |
bw steht jetzt für bewertungen und s für spiele, in der ganzen Abfrage, sogar in SELECT, das vor FROM kommt: Die Datenbank liest die ganze Abfrage, bevor sie sie ausführt. Ein Alias ist meist der erste Buchstabe des Tabellennamens oder ein paar Buchstaben, sodass klar ist, welche Tabelle welche ist. Bei Tabellen ist AS optional: FROM bewertungen bw JOIN spiele s ON … bedeutet dasselbe, und du siehst es oft so geschrieben.
s.titel ist ein qualifizierter Spaltenname: der Alias der Tabelle (oder ihr Name, wenn sie keinen Alias hat), ein Punkt und der Name der Spalte. Im Ergebnis heißt die Spalte nur titel. Sobald eine Tabelle einen Alias hat, benutze den Alias überall: Der eigene Name der Tabelle funktioniert in dieser Abfrage nicht mehr, und bewertungen.sterne würde mit dem Fehler no such column: bewertungen.sterne enden.
Qualifizierte Namen sind Pflicht, wenn beide Tabellen eine Spalte mit demselben Namen haben. positionen und spiele haben beide einen preis, und wenn du nur preis schreibst, weiß die Datenbank nicht, welchen du meinst:
SELECT titel, preis, menge
FROM positionen AS p
JOIN spiele AS s ON p.spiel_id = s.id;Error on line 1: ambiguous column name: preisMehrdeutig (englisch „ambiguous“) heißt „kann mehr als eines bedeuten“. SQLite rät nicht, und das ist gut: Es macht einen großen Unterschied, ob du den Preis bekommst, den der Kunde gezahlt hat (p.preis), oder den Preis des Spiels im Katalog (s.preis). Dasselbe gilt für id, das bestellungen, kunden und spiele alle haben. Eine Spalte, die nur in einer der Tabellen vorkommt, wie titel, funktioniert auch ohne Alias, aber in einer Abfrage mit Join ist es eine gute Gewohnheit, jede Spalte zu qualifizieren. Wer die Abfrage liest (du, in einem Monat), sieht sofort, woher jede Spalte kommt.
Wenn du dieselbe Spalte aus beiden Tabellen haben willst, benenne sie mit AS um, wie du in Lektion 2 gelernt hast, damit das Ergebnis nicht zwei Spalten mit demselben Namen hat:
SELECT b.id AS bestellung_id, k.id AS kunde_id, k.name
FROM bestellungen b
JOIN kunden k ON b.kunde_id = k.id
ORDER BY b.id;| bestellung_id | kunde_id | name |
|---|---|---|
| 1 | 1 | Emma Becker |
| 2 | 2 | Lukas Neumann |
| … | … | … |
Beachte ORDER BY b.id: Nur id wäre auch dort mehrdeutig.
So schreibst du es:
Anweisungen
- 1
Die Abfrage im Editor sollte die Bestellungen mit ihrem Status und der E-Mail-Adresse des Kunden auflisten, endet aber mit einem Fehler. Führe sie aus und lies den Fehler. Behebe ihn dann: Die
idsoll die der Bestellung sein, schreibe also stattdessenbestellungen.id, in SELECT und in ORDER BY. Das Ergebnis beginnt dann so:id bestellt_am status email 1 2024-01-20 bezahlt emma.becker@mail.de 2 2024-02-14 bezahlt lukas.neumann@mail.de 3 2024-02-29 bezahlt olivia@braunfamilie.net … … … … - 2
Mache die Abfrage jetzt mit Aliasen kürzer:
bfürbestellungenundkfürkunden. Benutze sie überall in der Abfrage, auch in ON. Das Ergebnis bleibt gleich. - 3
Schreibe darunter eine Abfrage, die jede Position jeder Bestellung mit beiden Preisen zeigt: die
bestellung_id, dentiteldes Spiels, seinen Preis im Katalog alslistenpreisund den Preis, den der Kunde gezahlt hat, alsgezahlt. Benutze die Aliasepfürpositionenundsfürspieleund sortiere die Zeilen nachbestellung_idvom höchsten Wert, dann nachtitel. Bestellung 28 aus dem Black-Friday-Angebot zeigt den Unterschied:bestellung_id titel listenpreis gezahlt 30 Bakery Story 15 15 30 Moon Farm 20 20 29 Knight's Oath 60 60 28 Shadow Ninja 25 15 28 Zombie Town 30 20 … … … …