Bobby: Join Problem über ODBC

Moin

ich habe ne Access-Datenbank (mdb) auf die ich über ODBC und PHP zugreife. Normale SQL-Statements sind kein Problem. auch einfache Join funktionieren. Aber sobald ich 2 Joins ausführen will erscheint der Fehler:

Warning: odbc_exec() [function.odbc-exec]: SQL error: [Microsoft][ODBC Microsoft Access Driver] Syntaxfehler (fehlender Operator) in Abfrageausdruck '(b.ID=flight.to) INNER JOIN plane AS c ON (c.ID=flight.plane)'., SQL state 37000 in SQLExecDirect in D:\xampp\xampp\htdocs\flugbuchung\inc\std\basicdb.class.php on line 44
SELECT flight.time, b.name AS destination FROM flight INNER JOIN airport AS b ON (b.ID=flight.to) INNER JOIN plane AS c ON (c.ID=flight.plane) WHERE from=1
37000

dazugehörige SQL-Abfrage:

  
SELECT flight.time, b.name AS destination FROM flight INNER JOIN airport AS b ON (b.ID=flight.to) INNER JOIN plane AS c ON (c.ID=flight.plane) WHERE `from`=1  

Leider bin ich mit der korrekten Syntax für mehrere Joins für ODBC nicht so vertraut. Wer kann mir nen Tip geben wie ich mehrere Joins ausführen kann?

Gruß Bobby

--
-> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
### Henry L. Mencken ###
-> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
## Viktor Frankl ###
ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
  1. Hi!

    SELECT flight.time, b.name AS destination FROM flight INNER JOIN airport AS b ON (b.ID=flight.to) INNER JOIN plane AS c ON (c.ID=flight.plane) WHERE from=1

    Kann es sein, dass to ein reserviertes Wort ist und es deswegen nicht will? Vielleicht musst du einfach nur die Klammern weglassen. Auf alle Fälle dürften `` nicht die für Access passenden Bezeichner-Quote-Zeichen sein.

    Lo!

    1. Moin

      Ähm, neeee... einfach blöder Dialekt:

      SELECT Flight.time, Airport.name AS destination, Plane.name AS plane FROM Plane INNER JOIN (Airport INNER JOIN Flight ON (Airport.ID = Flight.to)) ON Plane.ID = Flight.plane WHERE Flight.from=4

      diese Abfrage funktioniert nun. Ist ganz schön gewöhnungsbedürftig.

      Gruß Bobby

      --
      -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
      ### Henry L. Mencken ###
      -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
      ## Viktor Frankl ###
      ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
      1. Hallo,

        SELECT Flight.time, Airport.name AS destination, Plane.name AS plane FROM Plane INNER JOIN (Airport INNER JOIN Flight ON (Airport.ID = Flight.to)) ON Plane.ID = Flight.plane WHERE Flight.from=4

        diese Abfrage funktioniert nun.

        kann ich mir nicht vorstellen. Bei mir meckert Jet-SQL wegen der Backticks. Die mag Jet-SQL genausowenig wie ich :-)

        Freundliche Grüße

        Vinzenz

        1. Moin

          Muss dich enttäuschen. Bei mir funktioniert die Abfrage wirklich tadellos.

          Gruß Bobby

          --
          -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
          ### Henry L. Mencken ###
          -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
          ## Viktor Frankl ###
          ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
          1. Moin

            so, hab doch noch ein Problem. ORDER By will er nicht schlucken. Warum?

            SELECT Flight.to, Airport.name AS destination, Plane.name AS plane, Flight.time FROM Plane INNER JOIN (Airport INNER JOIN Flight ON (Airport.ID = Flight.to)) ON Plane.ID = Flight.plane WHERE Flight.from=4 AND Flight.time>=CDbl(#10/12/2001 00:00:00#) AND Flight.time<=CDbl(#10/12/2001 23:59:59#) ORDER BY Flight.time

            Fehler: Warning: odbc_exec() [function.odbc-exec]: SQL error: [Microsoft][ODBC Microsoft Access Driver] Sie wollten eine Abfrage ausführen, die den angegebenen Ausdruck 'Flight.time' nicht als Teil der Aggregatfunktion einschließt., SQL state 37000 in SQLExecDirect in ...

            Hat noch jemand nen Tip?

            Gruß Bobby

            --
            -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
            ### Henry L. Mencken ###
            -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
            ## Viktor Frankl ###
            ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
            1. Moin

              Nachtrag: Habe funktion nochmal angepasst (mit Between) ändert aber nix dran das ich keine Aggregatfunktion in dem Statement enthalten habe aber trotzdem diese dämliche fehlermeldung erscheint.

              Neuer Code:

                
              SELECT Flight.to, Airport.name AS destination, Plane.name AS plane, Flight.time FROM Plane INNER JOIN (Airport INNER JOIN Flight ON (Airport.ID = Flight.`to`)) ON Plane.ID = Flight.plane WHERE Flight.`from`=4 AND Flight.time BETWEEN CDbl(#10/12/2001 00:00:00#) AND CDbl(#10/12/2001 23:59:59#) ORDER BY Flight.time  
              
              

              Gruß Bobby

              --
              -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
              ### Henry L. Mencken ###
              -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
              ## Viktor Frankl ###
              ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
              1. Moin

                OK. Problem gelöst. ein GROUP BY über alle Felder in der entsprechenden Reihenfolge bringt das gewünschte Ergebnis.

                Gruß Bobby

                --
                -> Für jedes Problem gibt es eine Lösung, die einfach, sauber und falsch ist! <-
                ### Henry L. Mencken ###
                -> Nicht das Problem macht die Schwierigkeiten, sondern unsere Sichtweise! <-
                ## Viktor Frankl ###
                ie:{ br:> fl:{ va:} ls:< fo:) rl:( n4:( de:> ss:) ch:? js:( mo:} sh:) zu:)
            2. Hallo,

              so, hab doch noch ein Problem. ORDER By will er nicht schlucken. Warum?

              easy :-)

              SELECT Flight.to, Airport.name AS destination, Plane.name AS plane, Flight.time FROM Plane INNER JOIN (Airport INNER JOIN Flight ON (Airport.ID = Flight.to)) ON Plane.ID = Flight.plane WHERE Flight.from=4 AND Flight.time>=CDbl(#10/12/2001 00:00:00#) AND Flight.time<=CDbl(#10/12/2001 23:59:59#) ORDER BY Flight.time

              Fehler: Warning: odbc_exec() [function.odbc-exec]: SQL error: [Microsoft][ODBC Microsoft Access Driver] Sie wollten eine Abfrage ausführen, die den angegebenen Ausdruck 'Flight.time' nicht als Teil der Aggregatfunktion einschließt., SQL state 37000 in SQLExecDirect in ...

              Hat noch jemand nen Tip?

              klar: time ist in Jet-SQL ein reserviertes Wort (der Link sollte Dir bekannt vorkommen).

              Freundliche Grüße

              Vinzenz

    2. Hallo dedlfix,

      SELECT flight.time, b.name AS destination FROM flight INNER JOIN airport AS b ON (b.ID=flight.to) INNER JOIN plane AS c ON (c.ID=flight.plane) WHERE from=1

      Kann es sein, dass to ein reserviertes Wort ist und es deswegen nicht will?

      to ist in Jet-SQL ein reserviertes Wort.

      Auf alle Fälle dürften `` nicht die für Access passenden Bezeichner-Quote-Zeichen sein.

      Übliche Bezeichner-Quote-Zeichen bei Jet-SQL sind (wie bei T-SQL) die eckigen Klammern.

      Vielleicht musst du einfach nur die Klammern weglassen.

      Der QBE-Editor (Query by example) von Access erzeugt typischerweise sehr viele (auch redundante) Klammern. Nach meinen Erfahrungen erhält man diese Meldung, wenn man die einzelnen Join-Operationen *nicht* klammert. Die Klammerung (hier bei zwei INNER JOIN-Operationen) muss so erfolgen, wie im Artikel Fortgeschrittene Jointechniken verwendet, d.h. die Reihenfolge der Joins *muss* bei Jet-SQL durch die Klammerung vorgegeben werden:

      SELECT  
          flight.time,  
          b.name AS destination  
      FROM (  
              flight  
          INNER JOIN  
              airport AS b  
          ON  
              b.ID = flight.[to]  
      )  
      INNER JOIN  
          plane AS c  
      ON  
          c.ID=flight.plane  
      WHERE  
          [from] = 1;  
      
      

      Natürlich kann man hier auch umgekehrt herum klammern.

      Anmerkungen: Statt b und c greife lieber zu etwas sprechenderen Aliasnamen.

      Freundliche Grüße

      Vinzenz