JOIN-Befehl?
Ben
- datenbank
0 Vinzenz0 Ben0 Philipp Hasenfratz0 Ben
0 Juhu! :-)
Ben
Hallo,
ich möchte heute an meiner CD-Datenbank arbeiten.
Ich habe 2 Tabellen. Eine mit einer CD-Übersicht und eine für die jeweiligen Inhalte. Die Tabelle mit den Inhalten bekommt ein Feld, in das jeweils die ID der CD eingetragen wird, zu der die Inhalte gehören. So weit bin ich nun dank Hilfe von Sönke, Vinzenz und Tom2 (vielen Dank nochmal an dieser Stelle) mit meinem denken. Umsetzen werde ich es dann wohl nachher.
Wie funktioniert denn nun hinterher der Abruf der Daten? Ich möchte ja dann die CDs mit den Daten der CD-Übersicht ausgeben und auch die jeweiligen Inhalte einfügen. Ich wurde dabei auf den JOIN-Befehl verwiesen und habe darüber auch nachgelesen. Jedoch weiß ich nicht wirklich, wie ich das dann angeben muss.
Könnte mir da jemand mal die Funktionsweise dieses Befehls erklären oder so? Wäre wirklich nett. :)
Viele Grüße
Ben
Hallo Ben,
Wie funktioniert denn nun hinterher der Abruf der Daten? Ich möchte ja dann die CDs mit den Daten der CD-Übersicht ausgeben und auch die jeweiligen Inhalte einfügen. Ich wurde dabei auf den JOIN-Befehl verwiesen und habe darüber auch nachgelesen. Jedoch weiß ich nicht wirklich, wie ich das dann angeben muss.
Erste Klarstellung:
JOIN ist kein Befehl, sondern ein optionaler Bestandteil der SELECT-Anweisung.
Ein JOIN verbindet zwei Tabellen zu einer einzigen
T_CD JOIN T_Inhalt -> T_C (Ergebnis)
Wie die Ergebnistabelle aussieht, hängt
a) von der Art des JOINs
b) von den Ausgangstabellen ab (Wer hätte das gedacht? *g*)
Die Verknüpfung erfolgt über ein gemeinsames Feld (Spalte) beider Tabellen. Dieses Feld kann in beiden Tabellen _unterschiedliche_ Namen tragen, meistens jedoch wird der Name gleich lauten. Das macht _Dir_ als Datenbankentwerfer die Arbeit leichter.
Dramatisch vereinfachte Datenbankgrundlagen:
Die meisten Tabellen verfügen über ein Feld, über das ein Datensatz innerhalb der Tabelle eindeutig identifiziert werden kann: Dieses Feld ist dann indiziert, mit einem eindeutigen Index (UNIQUE), genauer gesagt Träger des Primärschlüssels (PRIMARY KEY)
Taucht dieses Feld in einer zweiten Tabelle auf, um so den zugehörigen Datensatz aus der ersten Tabelle zu identifizieren, so nennt man dieses Feld in der zweiten Tabelle Fremdschlüssel aus Tabelle 1.
So weit noch klar?
Zu Deinem CD-Beispiel
Beispiele:
T_CD T_Inhalt
CD_ID | CD_Titel Inhalt_ID | CD_ID | Songtitel
---------------- -----------------------------
1 | Blabla 1 | 1 | bla 1
2 | xxx 2 | 1 | bla 2
3 | 1 | bla 3
4 | 2 | x 1
5 | 2 | x 2
Die natürliche Sache der Welt ist die, dass Du in der Ergebnistabelle sehen willst, welcher Songtitel auf welcher CD ist:
T_CD natürlicher JOIN T_Inhalt -> T_Ergebnis
CD_ID | CD_Titel | Inhalt_ID | Songtitel
----------------------------------------
1 | Blabla | 1 | bla 1
1 | Blabla | 2 | bla 2
1 | Blabla | 3 | bla 3
2 | xxx | 4 | x 1
2 | xxx | 5 | x 2
Den natürlichen JOIN erhälst Du mit folgender SELECT-Anweisung:
SELECT T_CD.*, T_Inhalt.Inhalt_ID, T_Inhalt.Songtitel
FROM T_CD
INNER JOIN T_Inhalt ON T_CD.CD_ID = T_Inhalt.CD_ID;
So was, oder noch weniger Spalten (Inhalt_ID ist überflüssig) willst Du meistens haben.
Lässt Du die JOIN-Anweisung weg, so erhälst Du den CROSS JOIN, das ist das kartesische Produkt der beiden Tabellen, d.h. jede mögliche Kombination jeden Datensatzes aus T_CD mit jedem Datensatz aus T_Inhalt. In unserem Beispiel wären das 10 Datensätze:
SELECT T_CD.*, T_Inhalt.Inhalt_ID, T_Inhalt.Songtitel
FROM T_CD;
Das werden sehr schnell sehr viele Datensätze, der CROSS JOIN ist _meistens_ ein Fehler.
Beim natürlichen JOIN taucht das Feld, über das die Verknüpfung realisiert ist, nur einmal auf. Nimmst Du alle Spalten aus T_CD und alle aus T_Inhalt, so hast Du den Equi-Join:
SELECT T_CD.*, T_Inhalt.*
FROM T_CD
INNER JOIN T_Inhalt ON T_CD.CD_ID = T_Inhalt.CD_ID;
Zum guten Schluss: Ist der Verknüpfungsoperator kein Gleichheitszeichen, so nennt man das einen Theta-Join (Beispiel denke Dir bitte selbst aus)
Willst Du jetzt beispielsweise wissen, welche Songs auf der CD BlaBla sind, dann musst Du zu Deiner SELECT-Anweisung eine WHERE-Klausel hinzufügen:
SELECT T_CD.*, T_Inhalt.Inhalt_ID, T_Inhalt.Songtitel
FROM T_CD
INNER JOIN T_Inhalt ON T_CD.CD_ID = T_Inhalt.CD_ID
WHERE T_CD.Titel = 'BlaBla';
Bist Du nur daran interessiert, wieviele Songs auf den CDs sind, so kannst Du mit Aggregatfunktionen arbeiten:
SELECT T_CD.Titel, COUNT (T_Inhalt.CD_ID) AS Anzahl
FROM T_CD
INNER JOIN T_Inhalt ON T_CD.CD_ID = T_Inhalt.CD_ID
GROUP BY T_CD.Titel;
Hier habe ich zusätzlich der zweiten Spalte mit AS einen anderen Namen, nämlich 'Anzahl' gegeben.
Prinzipiell wäre es nicht verkehrt, Dir irgendwoher ein vernünftiges Tutorial zu SQL zu besorgen. Leider weiß ich im Moment keinen Link zu sowas :-(
Gruss,
Vinzenz
Hi Vinzenz,
vielen, vielen Dank für diese ausführliche Erläuterung. :)
Werde ich mir nach der Arbeit heute Abend mal ganz in Ruhe durchlesen und durcharbeiten. Bin sicher, dass ich es dann hinbekommen werde!
Nach guten Tutorials habe ich auch schon gesucht, aber gute habe ich bislang noch nicht finden können. Mal sehen, was meine nächste Google-Session noch bringt. ;-)
Viele Grüße
Ben
Halihallo Vinzenz
Als erstes: Gute Einführung, Vinzenz! Nachfolgend noch ein, zwei Anmerkungen.
Dramatisch vereinfachte Datenbankgrundlagen:
Datenbankgrundlagen in einem Posting zu verfassen impliziert bereits die
Unvollständigkeit :-)
T_CD natürlicher JOIN T_Inhalt -> T_Ergebnis
Den natürlichen JOIN erhälst Du mit folgender SELECT-Anweisung:SELECT T_CD.*, T_Inhalt.Inhalt_ID, T_Inhalt.Songtitel
FROM T_CD
INNER JOIN T_Inhalt ON T_CD.CD_ID = T_Inhalt.CD_ID;
Wenn du schon natürlicher JOIN sagst, dann mach den auch:
SELECT T_CD.*, T_Inhalt.Inhalt_ID, T_Inhalt.Songtitel
FROM T_CD NATURAL JOIN T_Inhalt
fertig. Dein Query ist zwar genau das selbe, aber länger (zudem kommt dort das Wort
NATURAL nicht vor)... Optional über einen Equi-Join (Join über Gleichwertigkeit von
Attributen).
SELECT T_CD.*, T_Inhalt.Inhalt_CD, T_Inhalt.Songtitel
FROM T_CD JOIN T_Inhalt USING (CD_ID)
SELECT T_CD.*, T_Inhalt.Inhalt_ID, T_Inhalt.Songtitel
FROM T_CD;
FROM T_CD, T_Inhalt (nur der Vollständigkeitshalber)
Beim natürlichen JOIN taucht das Feld, über das die Verknüpfung realisiert ist, nur einmal auf. Nimmst Du alle Spalten aus T_CD und alle aus T_Inhalt, so hast Du den Equi-Join:
Was hat die Ausgabe der Spalten mit einem Equi-Join zu tun?
SELECT T_CD.*, T_Inhalt.*
FROM T_CD
INNER JOIN T_Inhalt ON T_CD.CD_ID = T_Inhalt.CD_ID;
USING statt ON, s. oben (deine Lösung ist zwar äquivalent, führt jedoch zu mehr
Tipparbeit)
Zum guten Schluss: Ist der Verknüpfungsoperator kein Gleichheitszeichen, so nennt man das einen Theta-Join (Beispiel denke Dir bitte selbst aus)
Nicht ganz. Ein Theta-Join _kann_, muss jedoch nicht ein Gleichheitszeichen haben. Es
sind alle Operatoren erlaubt. Beim Equi-Join wird das Gleichheitszeichen impliziert
(USING (Spalte) ist gleich ON t1.Spalte=t2.Spalte).
Prinzipiell wäre es nicht verkehrt, Dir irgendwoher ein vernünftiges Tutorial zu SQL zu besorgen. Leider weiß ich im Moment keinen Link zu sowas :-(
Ben: Im Archiv findest du einige.
Vielleicht gleich zu JOIN's: http://www.mysql.com/doc/en/JOIN.html, obwohl da
wohl etwas Grundwissen vorausgesetzt ist; aber zumindest die Syntax ist ersichtlich.
Viele Grüsse
Philipp
PS: Zu beachten ist, dass MySQL eine unvollständige Unterstützung für JOIN's hat. Einige
Möglichkeiten sind über mysql nur mit Theta-Verbund oder INNER JOIN umzusetzen. Auch
einige Queries, die ich hier gepostet habe, funktionieren möglicherweise nicht auf
MySQL.
Hallo Philipp,
auch dir natürlich: Vielen Dank! :-)
Werde mich wie gesagt später mit dem Probieren und genauem Durcharbeiten befassen, da ich das ganz in Ruhe machen möchte, um es dann auch richtig zu lernen. :-)
Viele Grüße
Ben
Hallo,
habe es geschafft, nachdem ich den Query so umformuliert habe:
SELECT cduebersicht.*, cdinhalt.titel FROM cduebersicht INNER JOIN cdinhalt USING (cdid)
Vielen Dank für Eure Hilfe. Werde mir die Erläuterungen mal ausdrucken, denn sie haben mir sehr beim Verstehen geholfen. :-)
Viele Grüße
Ben