Gast: Kann ein JOIN mehrere Tabellen umfassen?

Hallo,

per join möchte ich einen Personensatz hinzufügen. In dem Satz ist eine ort_id und den zugehörigen Ortssatz brauche ich auch:

LEFT JOIN  "personen" per3  
          ,"orte"     ort3  
ON         per3.id = xxx.person_id  
AND        ort3.id = per3.ort_id

Nun wird mir für diese Zeilen "1064: You have an error ..." angezeigt. Habe versucht, den Fehler durch Klammer setzen zu beheben, Fehler bleibt.

Ich habe erstmalig probiert, mit dem join zwei Tabellen ansprechen. Geht das?

Gruß, Gast

  1. Hallo,

    LEFT JOIN  "personen" per3

    ,"orte"     ort3
    ON         per3.id = xxx.person_id
    AND        ort3.id = per3.ort_id

    
    >   
    > Nun wird mir für diese Zeilen "1064: You have an error ..." angezeigt. Habe versucht, den Fehler durch Klammer setzen zu beheben, Fehler bleibt.  
    >   
    > Ich habe erstmalig probiert, mit dem join zwei Tabellen ansprechen. Geht das?  
      
    ja, selbstverständlich. Nur muss man auch zweimal das Schlüsselwort "JOIN" verwenden, siehe Artikel [Fortgeschrittene JOIN-Techniken](http://wiki.selfhtml.org/wiki/Artikel:DBMS_und_SQL/Fortgeschrittene_Jointechniken#Mehrere_Tabellen_mit_JOIN_verkn.C3.BCpfen_-_unterschiedliche_Joinspalten).  
      
      
    Freundliche Grüße  
      
    Vinzenz
    
    1. Hallo, Vinzenz,

      LEFT JOIN  "personen" per3

      ,"orte"     ort3
      ON         per3.id = xxx.person_id
      AND        ort3.id = per3.ort_id

        
      
      > > Ich habe erstmalig probiert, mit dem join zwei Tabellen ansprechen. Geht das?  
      > ja, selbstverständlich. Nur muss man auch zweimal das Schlüsselwort "JOIN" verwenden, siehe Artikel [Fortgeschrittene JOIN-Techniken](http://wiki.selfhtml.org/wiki/Artikel:DBMS_und_SQL/Fortgeschrittene_Jointechniken#Mehrere_Tabellen_mit_JOIN_verkn.C3.BCpfen_-_unterschiedliche_Joinspalten).  
        
      Also für \_jede\_ Tabelle einmal das Schlüsselwort JOIN. Ich wollte es synonym gebrauchen zu  
      ~~~sql
        
      FROM   "personen" per1  
            ,"orte"     ort1  
      WHERE  per1.id = xxx.person_id  
      AND    ort1.id = per1.ort_id
      

      da kann man mehrere Tabellen mit nur einmal FROM ansprechen.

      Geht also nicht.

      Gruß, Gast

      1. Das ist ja auch irgendwie ein JOIN. Nur sieht man nicht so deutlich was da passiert.

        1. Das ist ja auch irgendwie ein JOIN. Nur sieht man nicht so deutlich was da passiert.

          Das ist nicht irgendwie ein Join. Das ist ein Join - ein impliziter Join.

          --
          Signaturen sind blöd!
  2. Hallo,

    mein Beispiel war, dass ein Personensatz ggf. auf einen zweiten Personensatz hinweist, den ich auch benötige. Beispiel wäre die Adresse einer Filiale, zu der ich immer den Hauptsitz brauche.

    Das Verfahren mit JOIN ist doch recht umständlich. Wenn ich die ID beider Sätze im Voraus kennen würde, ginge es so:

    WHERE per1.id = '4711' OR per1.id = '0815'

    Ich kenne aber nur 4711, der auf 0815 hinweist. Gibt es einen Trick, als ersten Satz des SELECT die 4711 zu bekommen und - falls vorhanden - als zweiten Satz den referenzierten?

    Gruß, Gast

    1. Hallo,

      mein Beispiel war, dass ein Personensatz ggf. auf einen zweiten Personensatz hinweist, den ich auch benötige. Beispiel wäre die Adresse einer Filiale, zu der ich immer den Hauptsitz brauche.

      wenn Du keine Tabellen mit Beispieldaten, dem gewünschten Ergebnis und der Begründung dafür lieferst, dann ist das wie im Dunklen umhertappen. Sowas macht mir keinen Spass.

      Vielleicht suchst Du ja Subqueries, vielleicht willst Du auch überhaupt keine OUTER JOINS, dein Text oben hört sich danach an :-)

      Freundliche Grüße

      Vinzenz

      1. Hallo, Vinzenz,

        wenn Du keine Tabellen mit Beispieldaten, dem gewünschten Ergebnis und der Begründung dafür lieferst, dann ist das wie im Dunklen umhertappen. Sowas macht mir keinen Spass.

        Es handelt sich um einen Monster-Select, der jetzt schon acht JOINS hat. Da wird der Ort dazugeholt, verwendete Sprachen und Übersetzungstabellen. Ich versuche, das Teilproblem herauszulösen:

        id    name            ort_id  ueber_id
        ----- --------------- ------- --------
        0815  Aldi-Zentrale   13556   NULL
        4711  Aldi Frankfurt  17342   0815
        4712  Mustermann      16344   NULL

        Mit einem (und nur einem) SELECT greife ich id=4711 und möchte 0815 als zweiten Datensatz dazugeliefert bekommen. Wenn ich id=4712 greife, kommt nur ein Datensatz.

        Wenn ich die Zentrale mit einem JOIN dazuhole, muss die Spalte name ein zweites Mal benannt sein, etwa name2. Dadurch kann ich aber im folgenden PHP nicht dieselbe Routine für Filiale und Zentrale nutzen, das möchte ich aber gerne.

        Vielleicht suchst Du ja Subqueries, vielleicht willst Du auch überhaupt keine OUTER JOINS, dein Text oben hört sich danach an :-)

        Ist das mit einem Subquery zu machen?

        SELECT per1.name, ...
        FROM  personen per1
        WHERE per1.id = '4711' OR per1.id = (SELECT per2.id FROM personen per2 WHERE per2.id = per1.ueber_id)

        Nee *überleg*

        WHERE per1.id = '4711' OR per1.id = per1.ueber_id

        Nee, auch nicht. Hast du verstanden, wo mein Problem ist?

        Gruß, Gast

        1. Hallo,

          Es handelt sich um einen Monster-Select, der jetzt schon acht JOINS hat. Da wird der Ort dazugeholt, verwendete Sprachen und Übersetzungstabellen. Ich versuche, das Teilproblem herauszulösen:

          id    name            ort_id  ueber_id


          0815  Aldi-Zentrale   13556   NULL
          4711  Aldi Frankfurt  17342   0815
          4712  Mustermann      16344   NULL

          das sieht nach einer hierarchischen Beziehung aus. Hierarchische Beziehungen bereiten in relationalen Datenbanken durchaus Bauchgrimmen :-)

          Wenn es nur zwei Ebenen gibt, dann könntest Du den zweiten Datensatz per Selfjoin bekommen. Wie ich im Dir bereits bekannten Artikel schreibe, skalieren Selfjoins nicht besonders gut:

          Idee 1:

          SELECT  
              id,  
              name,  
              ort_id,  
              ueber_id  
          FROM  
              tabelle  
          WHERE  
              id = 4711  
          
          

          liefert Dir die Aldi-Filiale in Frankfurt

          Der Selfjoin:

          SELECT  
              t1.id,  
              t1.name,  
              t1.ort_id,  
              t1.ueber_id  
          FROM  
              tabelle t1  
          INNER JOIN  
              tabelle t2  
          ON  
              t1.id = t2.ueber_id  
          WHERE  
              t2.id = 4711
          

          liefert Dir die zugehörige Aldi-Zentrale zur Filiale in Frankfurt.

          Die UNION beider Abfragen liefert Dir die beiden gewünschten Datensätze:

          SELECT  
              id,  
              name,  
              ort_id,  
              ueber_id  
          FROM  
              tabelle  
          WHERE  
              id = 4711  
            
          UNION ALL  
            
          SELECT  
              t1.id,  
              t1.name,  
              t1.ort_id,  
              t1.ueber_id  
          FROM  
              tabelle t1  
          INNER JOIN  
              tabelle t2  
          ON  
              t1.id = t2.ueber_id  
          WHERE  
              t2.id = 4711  
          
          

          liefert die beiden gewünschten Datensätze

          Alternativ könntest Du mit einer Subquery arbeiten:

          SELECT          -- Gib mir  
              id,         -- den Datensatz  
              name,  
              ort_id,  
              ueber_id  
          FROM  
              tabelle  
          WHERE  
              id = 4711   -- bei dem die id 4711 ist  
          OR                          -- oder deren  
              id IN (                 -- id in der  
                  SELECT              -- Liste der  
                      t2.ueber_id     -- Werte der ueber_ids  
                  FROM                -- aus  
                      tabelle t2      -- der gleichen Tabelle enthalten ist  
                  WHERE               -- wobei nur die Datensätze betrachtet werden  
                      t2.id = 4711    -- deren id-Wert 4711 ist  
              )  
          
          

          Sobald Du mehr als zwei Ebenen betrachten musst, dann solltest Du Dein Konzept der einfachen Adjazenzliste überdenken. Vielleicht käme das Nested-Set-Modell in Frage, vielleicht auch der Closure-Tree.

          Das hängt durchaus von Deinen Daten und den typischen Operationen auf diesen Daten ab.

          Freundliche Grüße

          Vinzenz

          1. Hallo, Vinzenz,

            ganz herzlichen Dank für deine Mühe.

            Ich habe in der Zwischenzeit mit einem Subquery rumprobiert. Aber der UNION ALL wäre eine Alternative.

            Gruß, Gast