mkuhnert: mySQL: mehrere INNER JOINs

Hallo,

ich bastele mir gerade eine simple DVD Datenbank.
Diese besteht aus 4 Tabellen, die wie folgt aufgebaut sind:

Quellcode:

Tabelle "dvd"
id        int(11)
datum       timestamp
name        varchar(80)
beschr        text
genre        int(3)
dar1           int(3)
dar2           int(3)
dar3           int(3)
regie       int(11)
laufzeit    int(3)
fsk        int(2)
bew        int(1)
jahr        int(4)
verl        int(1)

Tabelle "genre"
id        int(11)
art           varchar(60)

Tabelle "darsteller"
id        int(11)
vorname       varchar(60)
nachname       varchar(60)

Tabelle "regie"
id        int(11)
vorname       varchar(60)
nachname       varchar(60)

Die Tabellen sind via Recordsets miteinander verbunden. D. h., im Eingabeformular der Tabelle "dvd"
kann per Listenfeld die Darsteller, der Regisseur und das Genre ausgewählt werden.

Nun möchte ich per SELECT und JOIN alle DVDs ausgeben, in der Art:

ID, Name, Beschr, genre, dar1, dar2, dar3, regie, ...

Dabei soll "genre, dar1, dar2, dar3 und regie" nicht die ID anzeigen, sondern den "korrekten" Wert,
also z. B. "Tom Cruise" als Darsteller und nicht "23" als ID .

Folgende SELECT-Anweisung habe ich gebastelt, welche nicht funktioniert:

Quellcode:

$query = "SELECT dvd.*, genre.art AS j_genre, darsteller.name AS j_darsteller, regie.name AS j_regie FROM dvd
         INNER JOIN genre ON dvd.genre=genre.id
         INNER JOIN darsteller ON dvd.dar1=darsteller.id
         INNER JOIN darsteller ON dvd.dar2=darsteller.id
         INNER JOIN darsteller ON dvd.dar3=darsteller.id
         INNER JOIN regie ON dvd.regie=regie.id";

Die Daten gebe ich dann prinzipiell so aus:

Quellcode:

echo $arr[name],$arr[j_genre],$arr[j_darsteller],$arr[j_regie]...

Zum einen glaube ich, dass INNER JOIN hier falsch ist (LEFT stattdessen?) und natürlich die Zuordnung von dar1,
dar2 und dar3 fehlt (hier wird ja nur miT AS ein darsteller zugeordnet). Aber wie bekomme ich das in der
SELECT-Anweisung hin...?

Weitere Info zur Relation: jede DVD hat mindestens einen Darsteller, max. drei Darsteller.

Ich hoffe ich war nicht zu ausführlich.
Bin über jeden Tipp sehr dankbar!

Gruss, Marc

  1. Tabelle "dvd"
    [...]
    Tabelle "genre"
    [...]
    Tabelle "darsteller"
    [...]
    Tabelle "regie"
    [...]
    Die Tabellen sind via Recordsets miteinander verbunden. D. h., im Eingabeformular der Tabelle "dvd"
    kann per Listenfeld die Darsteller, der Regisseur und das Genre ausgewählt werden.

    Erklär mir mal das mit den "darsteller", die sind im Datendesign nicht über eine "1:n"- bzw. "n:m"-Beziehung mit "dvd" verbunden. Da kann nicht funzen. Ausserdem haben die Schlüssel nicht exakt denselben Typ und die Datenfeldnamen sind wenig aussagekräftig, behindern Dich also bei der späteren Abfrageerstellung.
    Also "DVD_ID" statt "id" oder "DVD_Genre_ID", wenn auf "Genre_ID" verwiesen werden soll.

    Nun möchte ich per SELECT und JOIN alle DVDs ausgeben, in der Art:

    Also, jetzt mal in meiner Notation:
    SELECT
     DVD_Name,
     DVD_Jahr,
    -- ...
     Genre_Name,
     Regie_Name
    FROM
     DVDS
    JOIN
     Genre on (DVD_Genre_ID = Genre_ID)
    JOIN
     Regie on (DVD_Regie_ID = Regie_ID)

    Über den Typ des JOINs kann dann diskutiert werden, wenn es funzt.

    1. Hello,

      falls du dich außerdem mal über die Joins etwas schlauer machen willst, in SELFHTML gibts eine eigene Sektion zum Thema Datenbanken & Co.

      MfG
      Rouven

      --
      -------------------
      Unser Problem ist, dass wir eine Demokratie entwickelt haben, was nicht immer der richtige Weg ist  --  Bernie Ecclestone zu den lästigen Diskussionen um Regeländerungen in der Formel 1
  2. yo,

    zusätzlich zu dem schon gesagten, habe ich noch ein paar ergänzungen.

    Die Tabellen sind via Recordsets miteinander verbunden.

    sie sind über fremdschlüssel miteinander verbunden und nicht durch recordsets. das mag ein wenig kleinlich klingen, das gleiche vokabular zu benutzen, hilft aber ungemein. den hinweis, dass man dabei immer den gleichen datentyp verwenden sollte und über die m:n beizehung wurde dir schon gegeben.

    Zum einen glaube ich, dass INNER JOIN hier falsch ist (LEFT stattdessen?)

    ein OUTER JOIN (LEFT oder RIGHT) musst du nur verwenden, wenn es keine entsprechenden matches in einer oder mehreren der beteiligten tabellen gibt. in deinem fall hast du aber eher einen klassischen INNER JOIN.

    dar2 und dar3 fehlt (hier wird ja nur miT AS ein darsteller zugeordnet). Aber wie bekomme ich das in der
    SELECT-Anweisung hin...?

    die aggregat-funktion GROUP_CONCAT ist dein freund. ein sehr nützlicher helfer von mysql, den ich bei großen anderen dbms schmerzlich vermisse.

    Ilja

  3. Tabelle "dvd"
    [...]
    dar1           int(3)
    dar2           int(3)
    dar3           int(3)
    [...]
    Tabelle "darsteller"
    id        int(11)
    vorname       varchar(60)
    nachname       varchar(60)
    [...]
    Zum einen glaube ich, dass INNER JOIN hier falsch ist (LEFT stattdessen?) und natürlich die Zuordnung von dar1,
    dar2 und dar3 fehlt (hier wird ja nur miT AS ein darsteller zugeordnet).

    Brrr, jetzt habe ich es kapiert, Du arbeitest mit drei Darstellern ("dar<n>") pro Film. Versuchs doch mal mit einer "n:m"-Beziehung, also z.B.:

    --
    -- Tabelle "DVDs"
    --
    DVD_ID                 int(11)
    DVD_Titel              varchar(255)
    -- ... (weitere Angaben)
    --
    -- Tabelle "DVDs_Actors"
    --
    DVDs_Actors_ID         int(11)
    DVDs_Actors_DVD_ID     int(11)
    DVDs_Actors_Actor_ID   int(11)
    --
    -- Tabelle "Actors"
    --
    Actor_ID               int(11)
    Actor_DOB              datetime
    Actor_FirstName        varchar(255)
    Actor_LastName         varchar(255)
    Actor_IsPornStar       bit
    -- ... (weitere Angaben)

    Du benötigst dann neben der Tabellenverwaltung "DVDs" noch eine weitere für "Actors", wenn die aber stehen kannst Du die Darsteller korrekt den Filmen zuordnen.