Folgendes Video erklärt wie man Tabellen in SQL verbindet:
Tabellen in SQL-Abfragen verbinden
Eine DB beinhaltet Tabellen, welche logisch zusammengehören.
Will man z.B. wissen von welchem Interpreten welches Lied ist,
so muss man in der SQL-Abfrage Tabellen verbinden.
Die SQL Anfrage
SELECT * FROM table1, table2;
liefert ein kartesisches Produkt,
d.h. in der Ergebnistabelle ist jede Zeile von table1
mit jeder Zeile von table2 verbunden.
Beispiel Kreuzprodukt
Mit den Tabellen table1:
t1id
t2id
a0
b3
a1
b4
a2
b4
t2id
b3
b4
Liefert SELECT * FROM table1, table2; folgendes Ergebnis:
table1.t1id
table1.t2id
table2.t2id
a0
b3
b3
a0
b3
b4
a1
b4
b3
a1
b4
b4
a2
b4
b3
a2
b4
b4
Hier wird jeder Datensatz von table1 mit jedem Datensatz
table2 verbunden.
Um Tabellen "richtig" zu verbinden muss man das Ergebnis auf Datensätze
einschränken, in welchen der Primär- und Fremdschlüssel übereinstimmen.
Hierzu gibt es 2 Möglichkeiten.
Verbinden über WHERE
Gibt man im WHERE-Teil der SQL-Abfrage an, dass der Primärschlüssel der
2. Tabelle gleich dem Fremdschlüssel der ersten Tabelle sein muss, so
werden nur "passende" Datensätze geliefert.
Im obigen Beispiel muss an
SELECT * FROM table1, table2 noch WHERE table2.t2id=table1.t2id
angehängt werden.
Beispiel zum Verbinden über WHERE:
Mit den Tabellen table1:
t1id
t2id
a0
b3
a1
b4
a2
b4
t2id
b3
b4
Liefert SELECT * FROM table1, table2 WHERE table2.t2id=table1.t2id; folgendes Ergebnis:
table1.t1id
table1.t2id
table2.t2id
a0
b3
b3
a1
b4
b4
a2
b4
b4
Hier werden nur Datensätze geliefert in welchen der Fremdschlüssel
t2id aus table1 mit dem Primärschlüssel
t2id aus table2 übereinstimmt.
Beim Verbinden über WHERE bildet das Datenbank-Mangement-System (DBMS)
zuerst das kartesische Produkt,
dies kann zu extrem großen Zwischentabellen führen.
Bsp.: 3 Tabellen mit je 1000 Datensätzen werden verknüpft:
Da jeder Datensatz von jeder der 3 Tabellen mit jedem Datensatz der andern verbunden wird
entsteht eine Zwischentabelle mit 1.000*1.000*1.000 = 1.000.000.000 Zeilen!
Aus dieser Milliarde Datensätze werden dann mit dem WHERE die passenden
z.B. 1000 Datensätze ermittelt.
Die benötigt viel Zeit und Speicher.
Verbinden über INNER JOIN
Um große Zwischentabellen zu vermeiden können Tabellen bereits im FROM-Teil
verbunden werden.
Der FROM-Teil sieht dann folgendermaßen aus:
SELECT *
FROM tabelle1
INNER JOIN tabelle2 ON tabelle1.PK = tabelle2.FK
INNER JOIN tabelle3 ON tabelle2.FK = tabelle3.PK
...
Das heißt an die erste Tabelle (tabelle1) wird die Tabelle2 mit INNER JOIN
angehängt und anschließend mit ON angegeben, welcher Primärschlüssel (PK) gleich
welchem Fremdschlüssel (FK) sein muss.
Beispiel zum Verbinden über WHERE:
Mit den Tabellen table1:
t1id
t2id
a0
b3
a1
b4
a2
b4
t2id
b3
b4
Liefert SELECT * FROM table1 INNER JOIN table2 ON table2.t2id=table1.t2id;
folgendes Ergebnis:
table1.t1id
table1.t2id
table2.t2id
a0
b3
b3
a1
b4
b4
a2
b4
b4
Hier werden nur Datensätze geliefert in welchen der Fremdschlüssel
t2id aus table1 mit dem Primärschlüssel
t2id aus table2 übereinstimmt.
Und dies ohne vorher eine große Zwischetabelle zu erzeugen.
Hier werden nur die Datensätze in der Zwischentabelle gespeichert,
welche zusammenpassen. Somit ist die Zwischentabellen viel kleiner.
Am effektivsten ist es, wenn man mit der kleinsten Tabelle beginnt.
Aufgabe 1
Gegeben ist eine CD-Datenbank mit folgenden Tabellen:
Geben Sie alle Liednamen aus, welche auf der CD mit CDID 0 sind
SELECT name
FROM lied
INNER JOIN aufcd ON lied.id = liedid
WHERE cdid=0;
Geben Sie alle Liednamen (als Song) mit zugehörigem CD-Titel (als CD) aus.
SELECT name AS Song, titel AS "CD-Titel"
FROM cd
INNER JOIN aufcd ON cd.cdid = aufcd.cdid
INNER JOIN lied ON lied.id = liedid;
Geben Sie alle Lied-Titel (als Lied) mit Interpretennamen (als Interpret) aus.
SELECT lied.name AS "Lied-Titel",
interpret.name AS Interpret
FROM Lied
INNER JOIN von ON lied.id= von.liedid
INNER JOIN interpret ON interpret.id = von.intid
Geben Sie alle Lied-Titel aus, welche von einer Band gespielt werden, welche keine Stilrichtung besitzt.
SELECT lied.name
FROM Lied
INNER JOIN von ON lied.id= von.liedid
INNER JOIN interpret ON interpret.id = von.intid
WHERE interpret.Stilrichtung IS NULL;
Geben Sie alle Stilrichtungen von CD 1 aus ohne doppelte Nennungen.
SELECT DISTINCT stilrichtung
FROM cd
INNER JOIN aufcd ON cd.cdid = aufcd.cdid
INNER JOIN von ON aufcd.liedid=von.liedid
INNER JOIN interpret AS i ON i.id=von.intid
WHERE cdid=1;
Geben Sie alle Interpreten von CD 1 aus. Sortieren Sie diese alphabetisch und vermeiden sie doppelte
Datensätze.
SELECT DISTINCT i.Name
FROM cd
INNER JOIN aufcd ON cd.cdid = aufcd.cdid
INNER JOIN von ON aufcd.liedid=von.liedid
INNER JOIN interpret AS i ON i.id=von.intid
WHERE cdid=1
ORDER BY i.Name;
Geben Sie alle Lieder incl. Interpret aus, wo Lied und Interpret mit 'B' beginnt.
SELECT i.Name, lied.name
FROM lied
INNER JOIN von ON lied.id=von.liedid
INNER JOIN interpret AS i ON i.id=intid
WHERE lied.name LIKE 'B%' AND i.name LIKE 'B%';
Die Antwort ist "Bob Dylan" mit "Blowin' in the wind"
Aufgabe 2
Gegeben ist folgende Bestell-Datenbank.
Ein Kunde kann mehrere Bestellungen aufgeben welche wiederum aus mehreren Produkten bestehen.
Eine nicht ausgelieferte Bestellung hat im Feld Ausgeliefert den Wert NULL.
Ermitteln Sie alle Kunden, für welche Bestellungen noch ausgeliefert werden müssen.
SELECT k.name
FROM Kunde AS k
INNER JOIN Bestellung AS b ON k.id=b.kundenid
WHERE ausgeliefert IS NULL;
Geben Sie die Produktnamen, deren Preis und die Bestell-Nr der Bestellung 53 aus.
SELECT Name, Preis, NR
FROM Bestellung AS b
INNER JOIN Bestellt AS be ON b.NR=be.BestellNr
INNER JOIN Produkt AS p ON p.ID = be.PID
WHERE NR=53;
Geben Sie alle Bestellungen des Kunden 0 aus.
SELECT *
FROM Bestellung
WHERE KundenID=0;
Geben Sie alle Produkte (Name und Preis) aus, welche Kunde 0 bestellt hat.
SELECT Produkt.Name, Produkt.Preis
FROM Bestellung
INNER JOIN Bestellt ON Bestellung.NR=Bestellt.BestellNr
INNER JOIN Produkt ON Produkt.ID = Bestellt.Pid
WHERE KundenID=0;
Geben Sie alle Bestellungs-Nummern aus, welche nach Berlin geliefert werden.
SELECT Nr
FROM Kunde AS k
INNER JOIN Bestellung AS b ON k.id=b.Kundenid
WHERE Ort='Berlin';
Geben Sie alle Produkte aus welche nach Dresden geliefert werden.
SELECT p.id, p.name, p.preis
FROM Kunde AS k
INNER JOIN Bestellung AS b ON k.id=b.Kundenid
INNER JOIN Bestellt ON BestellNR=Nr
INNER JOIN Produkt AS p ON p.id = pid
WHERE Ort='Dresden';
Geben Sie alle Orte aus ohne doppelte zu nennen und absteigend sortiert.