Ben: JOIN-Befehl?

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

--
Phantasie ist wichtiger als Wissen. - Albert Einstein
  1. 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

    --
    Die FAQ </faq/> des Forums sind lesenswert und hilfreich.
    1. 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

      --
      Phantasie ist wichtiger als Wissen. - Albert Einstein
    2. 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.

      1. 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

        --
        Phantasie ist wichtiger als Wissen. - Albert Einstein
  2. 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

    --
    Phantasie ist wichtiger als Wissen. - Albert Einstein