JOINs mit Spotify
Lernziele
- Sie erkennen in einem Datenbankschema, über welche Tabellen Sie joinen müssen, um zwei Tabellen zu verbinden.
- Sie können gleichnamige Spalten mit
tabelle.spalteund Aliasen eindeutig ansprechen.- Sie können Daten aus n:m-Beziehungen über Verknüpfungstabellen auslesen und mit
WHERE,GROUP BY,HAVINGundLEFT JOINkombinieren.
Vom Bürogebäude zu Spotify
Auf der letzten Seite haben Sie drei Tabellen hintereinander verknüpft:
SELECT name, building_name, salary
FROM buildings
JOIN employees ON building_name = building
JOIN salaries ON role = role_name;
Die Tabelle in der Mitte, employees, war dabei der Schlüssel: Nur sie kennt sowohl das Gebäude als auch die Rolle — und über die Rolle den Lohn. In einem Gebäude arbeiten verschiedene Rollen, und jede Rolle kommt in mehreren Gebäuden vor — buildings und salaries stehen also in einer n:m-Beziehung, und employees verbindet die beiden.
Genau dieses Muster kennen Sie aus dem Kapitel Datenbank-Design: die Verknüpfungstabelle. Ab jetzt arbeiten wir wieder mit der normalisierten Datenbank spotify.db statt der flachen spotify_flat.db — und dort gibt es gleich drei solche Verknüpfungstabellen:
| Tabelle links | Tabelle in der Mitte | Tabelle rechts | |
|---|---|---|---|
| Büro | buildings | employees | salaries |
| Spotify | tracks | track_artists | artists |
| Spotify | tracks | track_albums | albums |
| Spotify | tracks | track_genres | genres |
Einen Unterschied gibt es: employees hat eigenen Inhalt (Namen, Dienstjahre). track_artists dagegen ist eine reine Verknüpfungstabelle — sie enthält praktisch nur IDs, die auf einen Song und einen Künstler zeigen. Wenn Sie also einen Song mit seinem Künstlernamen sehen möchten, brauchen Sie immer zwei JOINs — genau wie von buildings zu salaries.
Spaltennamen und Aliase
Bei buildings, employees und salaries konnten wir einfach building_name oder role schreiben, weil jeder Spaltenname nur in einer Tabelle vorkommt. In der Spotify-Datenbank ist das anders: track_id gibt es in tracks und in track_artists, eine Spalte name sogar in artists, albums und genres. Damit klar ist, welche Spalte gemeint ist, schreibt man tabelle.spalte:
SELECT tabelle1.spalte, tabelle2.spalte
FROM tabelle1
JOIN tabelle2 ON tabelle1.gemeinsame_spalte = tabelle2.gemeinsame_spalte;
Weil ausgeschriebene Tabellennamen die Abfragen schnell lang machen, gibt man den Tabellen meist einen kurzen Alias: Direkt hinter dem Tabellennamen steht die Abkürzung — FROM tracks t bedeutet «die Tabelle tracks, im Folgenden kurz t»:
SELECT t.track_name, a.name
FROM tracks t
JOIN track_artists ta ON t.track_id = ta.track_id
JOIN artists a ON ta.artist_id = a.artist_id;
Hier steht t für tracks, ta für track_artists und a für artists. Alle folgenden Beispiele verwenden diese Schreibweise.
Beispiele
Songs mit Künstlernamen
Um Songs mit ihren Künstlern zu sehen, gehen wir über die Verknüpfungstabelle track_artists:
Zwei JOINs nötigErst von
trackszutrack_artists, dann vontrack_artistszuartists— genau wie vonbuildingsüberemployeeszusalaries.
Songs mit Albumnamen
Auch die Album-Zuordnung läuft über eine Verknüpfungstabelle – ein Song kann auf mehreren Alben erscheinen:
Songs mit Genres
Dasselbe Prinzip gilt für Genres – auch hier brauchen wir eine Verknüpfungstabelle:
Kollaborationen sichtbar machen
Erinnern Sie sich an das Problem der flachen Tabelle, wo Ingrid Michaelson;ZAYN in einem einzigen Feld stand? In der normalisierten Datenbank sind beide Künstler einzeln gespeichert:
Alle Alben eines Songs
Da ein Song jetzt auf mehreren Alben erscheinen kann, können wir das mit einem JOIN sichtbar machen:
Songs, Künstler und Album zusammen
Sie können auch mehrere Tabellen in einer Abfrage verknüpfen:
JOIN mit Aggregatsfunktionen
JOINs lassen sich hervorragend mit den Aggregatsfunktionen kombinieren — so wie bei der Lohnsumme pro Gebäude.
Welche Künstler haben die meisten Songs?
Songs mit den meisten Künstlern
In wie vielen Genres ist ein Künstler vertreten?
LEFT JOIN in der Praxis
Sie kennen den LEFT JOIN bereits vom buildings-Beispiel: alle Zeilen der linken Tabelle, auch ohne Treffer rechts. Genau das macht ihn zum Werkzeug, um «verwaiste» Einträge zu finden.
Beispiel: Gibt es Alben ohne Songs?
Mit einem LEFT JOIN können wir prüfen, ob es Alben in der Datenbank gibt, zu denen kein Song gespeichert ist:
NULL-Werte als IndikatorWenn
tab.track_id IS NULList, bedeutet das: Dieses Album existiert in deralbums-Tabelle, aber es gibt keinen Song intrack_albums, der darauf verweist. MitWHERE ... IS NULLnach einemLEFT JOINfindet man also «verwaiste» Einträge.
Unterschied zwischen JOIN und LEFT JOIN
RIGHT JOINEin
RIGHT JOINkommt in der Praxis selten vor, weil man die Abfrage meist einfach umdrehen und einenLEFT JOINverwenden kann.
Aufgaben
Aufgabe 1: Songs und Alben
Zeigen Sie die Spalten track_name und den Albumnamen für die 10 populärsten Songs. Sortieren Sie nach Popularität absteigend.
Aufgabe 2: Alle Künstler eines Songs
Zeigen Sie alle Künstler des Songs «Blinding Lights», inklusive ihrer Position. Sortieren Sie nach Position.
Aufgabe 3: Genres eines Songs
Finden Sie alle Genres, die dem Song «Tippa My Tongue» von den Red Hot Chili Peppers zugeordnet sind.
HinweisUm den Hauptkünstler einzuschränken, joinen Sie auch
track_artistsundartistsund filtern mitta.position = 1.
Aufgabe 4: Alben der Beatles
Finden Sie alle Alben von «The Beatles» und zählen Sie, wie viele Songs pro Album in der Datenbank sind. Sortieren Sie nach Anzahl Songs absteigend.
Aufgabe 5: Durchschnittliche Tanzbarkeit pro Künstler
Finden Sie die 10 Künstler mit der höchsten durchschnittlichen Tanzbarkeit, aber nur solche, die mindestens 20 Songs in der Datenbank haben. Zeigen Sie Künstlername, durchschnittliche Tanzbarkeit (gerundet auf 3 Stellen) und Anzahl Songs.
Aufgabe 6: Kollaborationen finden
Finden Sie alle Songs, an denen mehr als 5 Künstler beteiligt sind. Zeigen Sie den Songtitel und die Anzahl der Künstler, sortiert nach Anzahl absteigend. Begrenzen Sie auf 15 Ergebnisse.
Aufgabe 7: Komplett-Abfrage
Erstellen Sie eine vollständige Übersicht: Zeigen Sie für die 10 populärsten Songs den Titel, den Hauptkünstler (Position 1), ein Album, das Genre, die Popularität und die Tanzbarkeit. Sortieren Sie nach Popularität absteigend.
HinweisDa ein Song mehrere Alben und Genres haben kann, erscheint er möglicherweise mehrfach im Ergebnis. Um nur eine Zeile pro Song zu bekommen, können Sie mit
GROUP BY t.track_idgruppieren undMIN(al.name)bzw.MIN(g.name)verwenden.
Zusammenfassung
Was Sie gelernt haben
- Verknüpfungstabellen lösen Viele-zu-Viele-Beziehungen (Songs ↔ Künstler, Songs ↔ Alben, Songs ↔ Genres) — wer von einer Seite zur anderen will, braucht zwei JOINs
- Gleichnamige Spalten sprechen Sie mit
tabelle.spaltean, kurze Aliase (FROM tracks t) halten die Abfragen lesbar- JOINs lassen sich mit WHERE, GROUP BY, HAVING und ORDER BY kombinieren
- Mit LEFT JOIN und
WHERE ... IS NULLfinden Sie verwaiste Einträge- Eine normalisierte Datenbank vermeidet Duplikate und Inkonsistenzen der flachen Tabelle