Announcement

Collapse
No announcement yet.

Über 3 Tabellen Left-Joinen...

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Über 3 Tabellen Left-Joinen...

    ... sollte doch bestimmt irgendwie machbar sein, oder?

    Die Ausgangslage

    Sprache: SQL
    Applikation: MS-Access (Version unbekannt)

    Die Mitarbeiter der Firma How2Join können sich am Mittag in der firmeninternen Kantine verpflegen. Ihnen steht dabei offen, ob sie die Dienste des meisterhaften Küchenchefs in Anspruch nehmen wollen, oder ob sie selbst von zu Hause etwas mitbringen.
    Die geschilderte Situation soll in einer Datenbank erfasst werden. (Klingt jetzt wie eine Schulaufgabe, ich weiss. Bei meinen Tabellen handelt es sich tatsächlich nicht um die unten dargestellten (oder oben im Beispiel beschriebenen) - ich habe dieses Beispiel nur der Anschaulichkeit wegen gewählt - denn sobald ich das Prinzip verstanden habe (wie man nämlich mehrere Tabellen verknüpfen kann, auch wenn sie z.B. NULL-Werte enthalten), kann ich es auch 1:1 auf meine Tabellen übertragen...)

    Bestellung
    Code:
    +-------------------------+
    | ID | Mitarbeiter | Fraß |
    |-------------------------|
    | 1  |      1      |   2  |
    | 2  |      1      |   3  |
    | 3  |      3      | NULL |
    | 4  |      2      |   1  |
    +-------------------------+

    Mitarbeiter
    Code:
    +-------------+
    | ID | Name   |
    |-------------|
    | 1  | Franz  |
    | 2  | Heidi  |
    | 3  | Paula  |
    +-------------+

    Fraß
    Code:
    +-------------+
    | ID | Fraß   |
    |-------------|
    | 1  | Döner  |
    | 2  | Fisch  |
    | 3  | Suppe  |
    | 4  | Pizza  |
    +-------------+
    Das gewünschte Endergebnis/Das Ziel
    Folgendes soll nach der Abfrage ausgegeben werden:
    Bestellung
    Code:
    +--------------------------+
    | ID | Mitarbeiter | Fraß  |
    |--------------------------|
    | 1  |   Franz     | Fisch |
    | 2  |   Franz     | Suppe |
    | 3  |   Paula     | NULL  |
    | 4  |   Heidi     | Döner |
    +--------------------------+
    Im Prinzip ziemlich simpel, oder? Ich möchte nichts weiter, als die entsprechende Mitarbeiter-ID durch den Namen des Mitarbeiters und die Fraß-ID durch den Namen des Gerichts ersetzen.


    Der Weg
    Tja, hier scheitere ich.

    Würde es sich nur um einen JOIN über zwei Tabellen handeln, bzw. müsste ich nicht herausfinden was sich hinter der Frass-ID verbirgt, würde es mir mit dieser Abfrage gelingen...

    PHP Code:
    SELECT B.IDM.Name AS MitarbeiterB.Frass
    FROM Bestellung 
    AS BMitarbeiter AS M
    WHERE B
    .Mitarbeiter=M.ID
    LEFT_JOIN_Tabelle
    Code:
    +--------------------------+
    | ID | Mitarbeiter | Frass |
    |--------------------------|
    | 1  |   Franz     |    2  |
    | 2  |   Franz     |    3  |
    | 3  |   Paula     |  NULL |
    | 4  |   Heidi     |    1  |
    +--------------------------+
    Nun, die Frage:
    Und dieses Ergebnis müsste ich nun nur noch irgendwie mit der Tabelle "Frass" LEFT-JOINEN... nur, wie geht das?

    Kann man obige Abfrage (die ja die richtige Tabelle für den entsprechenden LEFT-JOIN liefern würde) nicht einfach irgendwie in eine Abfrage einbauen, also im Stil von:

    PHP Code:
    SELECT LJT.IDLJT.MitarbeiterF.Frass
    FROM LEFT_JOIN_Tabelle 
    AS LJT
    LEFT JOIN Frass 
    AS F ON LJT.Frass=F.ID
    Oder eben, weil's die "LEFT_JOIN_Tabelle" ja nicht wirklich gibt (bzw. diese wahrscheinlich nur temporär irgendwo im RAM vorhanden sein wird), anstelle der Tabelle ganz einfach die Abfrage,welche die entsprechende Tabelle erzeugt?

    PHP Code:
    SELECT LJT.IDLJT.MitarbeiterF.Frass
    FROM 
    (SELECT B.IDM.Name AS MitarbeiterB.Frass
    FROM Bestellung 
    AS BMitarbeiter AS M
    WHERE B
    .Mitarbeiter=M.ID) AS LJT
    LEFT JOIN Frass 
    AS F ON LJT.Frass=F.ID
    Oder denke ich da irgendwie falsch? Oder liegt's doch an der Applikation?
    Denn irgendwie schimpft mir Access da über irgendwelche Syntaxfehler und da ich nur ein kleiner Anfänger bin, bin ich mit der Fehlersuche natürlich total überfordert...

    Ausser den etwas weiter unten erwähnten Büchern stehen mir bislang leider keine weiteren Informationsquellen zur Verfügung. Irgendwie bin ich mit googeln nicht mehr so richtig in Form... daher bin ich natürlich über jedes eBook oder Paper dankbar.


    The Dirty-Way
    Ich sitzt da nun schon gut zwei Tage dran und komm' irgendwie nicht so recht weiter... liegt einfach daran, dass ich nirgens was passendes finde.
    Google liefert nur Trash und in meinen Büchern (René Steiner - Grundkurs Relationale Datenbanken und Apress - The Programmers Guide to SQL) wird ebenfalls nicht darauf eingegangen.

    Mir ist nun aber eine Quick'n'Dirty-Lösung eingefallen, nur bin ich mit der nicht so recht glücklich...

    Ich könnte für alle, die ihr Essen selbst von zu Hause mitnehmen einen eigenen Eintrag hinzufügen, z.B.


    Fraß
    Code:
    +-------------+
    | ID | Fraß   |
    |-------------|
    | 1  | Döner  |
    | 2  | Fisch  |
    | 3  | Suppe  |
    | 4  | Pizza  |
    | 5  | EIGEN  |  <-- Eigenes Essen
    +-------------+
    Nun würden keine NULL-Werte mehr vorkommen...

    Bestellung
    Code:
    +-------------------------+
    | ID | Mitarbeiter | Fraß |
    |-------------------------|
    | 1  |      1      |   2  |
    | 2  |      1      |   3  |
    | 3  |      3      |   5  |
    | 4  |      2      |   1  |
    +-------------------------+
    ... und ich würde mit einer ziemlich simplen Abfrage zu meinem Ergebnis kommen.

    PHP Code:
    SELECT Frass.FrassMitarbeiter.NameBestellung.ID
    FROM
     Mitarbeiter
    ,
     
    Frass,
     
    Bestellung
    WHERE
    (Bestellung.Frass=Frass.ID) And (Bestellung.Mitarbeiter=Mitarbeiter.ID); 
    Nur macht mich das, wie gesagt, nicht wirklcih glücklich.
    Kann mir einer zeigen, wie das besser geht?

    Vielen Dank schonmal,
    Grüsse von Bernd, dem Boot



    Auf die Gefahr hin, mich zu früh zu freuen, aber: Es geht! Es geht!

    Den Code hier, bzw. die Überlegungen dazu (siehe weiter oben) habe ich hier während des schreibens, naja... ich sag mal, "aus dem Ärmel" geschüttelt... (hehe, auch eine Methode wenn man nicht mehr weiterkommt... das Problem plus die entsprechenden Überlegungen dazu +/- klar strukturiert in einem Posting verfassen und danach feststellen, dass man dadurch das Problem gelöst hat...)
    Just for Fun (da ich als SQL-Noob nicht wirklich daran glaubte, dass es so funktionieren würde) liess ich ihn dann doch mal über meine Tabellen rattern - und tatsächlich! Ich erhalte das richtige Ergebnis! Geil!

    Aus
    PHP Code:
    SELECT LJT.IDLJT.MitarbeiterF.Frass
    FROM 
    (SELECT B.IDM.Name AS MitarbeiterB.Frass
    FROM Bestellung 
    AS BMitarbeiter AS M
    WHERE B
    .Mitarbeiter=M.ID) AS LJT
    LEFT JOIN Frass 
    AS F ON LJT.Frass=F.ID
    Wird
    Code:
    +--------------------------+
    | ID | Mitarbeiter | Fraß  |
    |--------------------------|
    | 1  |   Franz     | Fisch |
    | 2  |   Franz     | Suppe |
    | 3  |   Paula     | NULL  |
    | 4  |   Heidi     | Döner |
    +--------------------------+
    Sooo, sorry für den Trouble hier =)
    Ich experimentiere noch ein wenig... anstatt nur mit 3 Tabellen nun mit n-Tabellen... vielleicht brauche ich eure Hilfe also doch noch.

    Grüsse und einen schönen Abend

    Nachtrag 2:
    Vielleicht noch als kleine Zusatzinfo... den obigen Code hatte ich so noch nicht als Abfrage in Access drin (hab' ihn also wirklich hier während des Schreibens "aus/durchgedacht"), aber ich habe wirklich viele ähnliche Abfragen erstellt - nur scheinbar (na, weil ich sie eben nicht so genau durchdacht habe wie oben und einfach unüberlegt auf gut Glück reingehackt habe) waren die allesamt fehlerhaft.
    Zuletzt editiert von b.dasboot; 03.10.2007, 22:05. Reason: HEUREKA!

  • #2
    Hallo Bernd,

    Vielleicht mal etwas Theorie
    Bei Joins unterscheidet man zwischen INNER und OUTER JOINs. Der INNER-Join ist das was du mit Bestellung und Mitarbeiter gemacht hast.
    [highlight=sql]
    select * from tab1
    left join tab2 on tab1.fkid = tab2.pkid
    [/highlight]
    Es werden also alle DS aus tab1 gelistet, die mindestens eine Entsprechung in fkid haben, die per pkid in Tab2 gefunden wird.
    Manchmal ist es nun schön auch die DS zu sehen, die keine Beziehung zu Tab2 haben, die also ihren "Fraß" von zu Hause mitbringen. Hier kommt dann der OUTER Join ins Spiel:
    [highlight=sql]
    select * from tab1
    left outer join tab2 on tab1.fkid = tab2.pkid
    [/highlight]
    Hier werden jetzt alle DS aus tab1 gelistet, die eine oder keine Entsprechung in fkid haben, die per pkid in Tab2 gefunden wird.
    Für dein Beispiel mußt du nun nur noch beide miteinander kombinieren:
    [highlight=sql]
    select a.id, b.Name, c.Fraß
    from (Bestellung a
    left join Mitarbeiter b on a.Mitarbeiter = b.ID)
    left outer join Fraß c on a.Fraß = c.ID
    [/highlight]

    Gruß Falk
    Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

    Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

    Comment

    Working...
    X