Kalle_B: Sytaxfehler bei JOIN

Hallo,

bin heute nicht so gut drauf und habe sicher nur eine Kleinigkeit übersehen, aber welche?

Fehlermeldung in phpMyAdmin:
#1054 - Unknown column 'evt1.von_slot_nr' in 'on clause'

SELECT
 evt1.id                evt1_id
,evt1.von_slot_nr       evt1_slot1
,evt1.bis_slot_nr       evt1_slot2
,evt2.id                evt2_id
,evb1.adress_id         evb1_adr_id
,anw1.slot_nr           anw_slot1
,anw2.slot_nr           anw_slot2

-- ALLE INTERESSENTEN:
FROM
 tm_events evt1
,tm_events evt2
,tm_eventbuchungen evb1

-- ZU JEDEM INTERESSENTEN DIE ANWESENHEIT IN BEIDEN SLOTS:
LEFT JOIN tm_anwesenheit anw1
ON       (anw1.adr_id=evb1.adress_id AND anw1.slot_nr=evt1.von_slot_nr)
LEFT JOIN tm_anwesenheit anw2
ON       (anw2.adr_id=evb1.adress_id AND anw2.slot_nr=evt1.bis_slot_nr)

WHERE     evt1.id=154 AND evt2.kurzname=evt1.kurzname AND evt2.lfd_nr=1
AND       evb1.wunsch_event_id=evt2.id

Mit oder ohne Klammer bei ON ergibt denselben Fehler, die Klammern sollen wohl sein:
http://dev.mysql.com/doc/refman/5.0/en/left-join-optimization.html

Wenn ich evt1.von_slot_nr durch 11 (den Wert, den evt1_slot1 ausgibt und evt1.bis_slot_nr durch 12 (= evt1_slot2) ersetze, läuft es rund.

LG Kalle

  1. yo,

    bin heute nicht so gut drauf und habe sicher nur eine Kleinigkeit übersehen, aber welche?

    solange das bier kalt ist, ist alles in butter....

    Fehlermeldung in phpMyAdmin:
    #1054 - Unknown column 'evt1.von_slot_nr' in 'on clause'

    die fehlermeldung kann verwirren, so als wenn es die spalte gar nicht geben würde. da steckt aber letztlich die falsche reihenfolge und besagt, so wie du die abfrage geschrieben hast und das dbms sie ausführt, kennt er die spalte -> noch <- nicht.

    nimm einfach mal eine explizite join schreibweise und dein problem sollte sich damit eventuell schon erledigen.

    Ilja

    1. yo,

      meine Absicht war, den folgenden Klopfer, der ohne Probs durchläuft, nachzubauen, Schritt für Schritt. In der Hoffnung, dass er schlanker wird.

      Also warum gibt das hier KEINEN Fehler:

      SELECT
       evt1.id                evt1_id
      ,evt1.von_slot_nr       evt1_slot1
      ,evt1.bis_slot_nr       evt1_slot2

      ,evt2.id                evt2_id
      ,evb1.adress_id         evb1_adress_id
      ,bzg1.gruppen_id        bzg1_gruppen_id
      ,count(evb4.gruppen_id) evb4_anz_mitglieder

      ,anw1.slot_nr           anw1_slot_nr
      ,kon1.aussteller2_id    kon1_aussteller2_id
      ,evb2.gebuchte_event_id evb2_gebuchte_event_id

      ,anw2.slot_nr           anw2_slot_nr
      ,kon2.aussteller2_id    kon2_aussteller2_id
      ,evb3.gebuchte_event_id evb3_gebuchte_event_id

      -- ZU BUCHENDES EVENT
      FROM      tm_events AS evt1

      -- ZUGEHOERIGES STAMM-EVENT
      LEFT JOIN tm_events AS evt2
      ON        evt2.owner_id=evt1.owner_id AND evt2.kurzname=evt1.kurzname AND evt2.lfd_nr=1
      -- ALLE UNGEBUCHTEN INTERESSENTEN ZU STAMM-EVENT
      LEFT JOIN tm_eventbuchungen AS evb1
      ON        evb1.wunsch_event_id=evt2.id AND evb1.gebuchte_event_id=0
      -- GRUPPE DES INTERESSENTEN
      LEFT JOIN tm_gruppen_besucher AS bzg1
      ON        bzg1.adress_id=evb1.adress_id

      -- ANWESENHEIT DES INTERESSENTEN, 1. SLOT
      LEFT JOIN tm_anwesenheit AS anw1
      ON        anw1.adr_id=evb1.adress_id AND anw1.slot_nr=evt1.von_slot_nr
      -- KONTAKT DES INTERESSENTEN SLOT 1
      LEFT JOIN tm_kontakte AS kon1
      ON        kon1.besucher_id=evb1.adress_id AND kon1.slot_nr=evt1.von_slot_nr
      -- EVENT DES INTERESSENTEN SLOT 1
      LEFT JOIN tm_eventbuchungen AS evb2
      ON        evb2.adress_id=evb1.adress_id AND ( evb2.von_slot_nr=evt1.von_slot_nr OR evb2.bis_slot_nr=evt1.von_slot_nr )

      -- ANWESENHEIT DES INTERESSENTEN, 2. SLOT
      LEFT JOIN tm_anwesenheit AS anw2
      ON        anw2.adr_id=evb1.adress_id AND anw2.slot_nr=evt1.bis_slot_nr
      -- KONTAKT DES INTERESSENTEN SLOT 2
      LEFT JOIN tm_kontakte AS kon2
      ON        kon2.besucher_id=evb1.adress_id AND kon2.slot_nr=evt1.bis_slot_nr
      -- EVENT DES INTERESSENTEN SLOT 2
      LEFT JOIN tm_eventbuchungen AS evb3
      ON        evb3.adress_id=evb1.adress_id AND ( evb3.von_slot_nr=evt1.bis_slot_nr OR evb3.bis_slot_nr=evt1.bis_slot_nr )

      -- ANZAHL GRUPPENMITGLIEDER FUER STAMM-EVENT
      LEFT JOIN tm_eventbuchungen AS evb4
      ON        evb4.wunsch_event_id=evt2.id AND evb4.gruppen_id=bzg1.gruppen_id AND evb4.gruppen_id>0

      WHERE     evt1.id = 154
      GROUP BY  evb4.gruppen_id, evb1.adress_id
      HAVING    kon1_aussteller2_id IS NULL
      AND       evb2_gebuchte_event_id IS NULL
      AND       kon2_aussteller2_id IS NULL
      AND       evb3_gebuchte_event_id IS NULL
      ORDER BY  evb4_anz_mitglieder DESC, bzg1_gruppen_id, evb1_adress_id

      Ergebnis:
      Zeige Datensätze 0 - 29 (37 insgesamt, die Abfrage dauerte 0.0345 sek.)

      1. yo,

        Also warum gibt das hier KEINEN Fehler:

        es liegt wie gesagt an der reihenfolge, wie das dbms deine abfrage ausführt. er verbindet ein tabelle nach der anderen miteinander. bei der anderen anweisung hat er einen LEFT JOIN anwenden wollen und dort kam eine spalte von einer tabelle vor, die er noch gar nicht eingebunden hatte. was bei impliziten joins vorne steht, muss noch lange nicht als erste tabelle von dem dbms genommen werden. oracle zum beispiel geht von rechts nach links bei impliziten joins vor.

        dein problem entstand also durch die vermischung der impliziten schreibweise von JOINS in kombination mit OUTER JOINS. bei deiner zweite abfrage hast du nur explzitite JOINS, die so aufgebaut, dass die richtige reihenfolge eingehalten wird.

        Ilja

        1. Hallo, Ilja,

          habe recherchiert nach explizit und habe ein grundsätzliches Verständnisproblem.

          Wenn ich den Tabellennamen tm_anwesenheit angebe statt der Abkürzung anw1 oder anw2 kann man doch eine Tabelle nicht mehrfach einbinden?

          Genau das brauche ich aber.

          Habe leider keine Idee, wie ich mein Problem angehen kann.

          Kalle

          1. habe recherchiert nach explizit und habe ein grundsätzliches Verständnisproblem.

            Ach so, implizit heisst OHNE Joins ...

            Das geht in meinem Fall wohl nicht, weil ich eine Negativ- Aussage brauche.

            Aufgabe:
            Finde alle Besucher, die in den Vortrag XYZ wollen um 12:00 Uhr:
            Die Besucher müssen:

            • sich für diesen Vortrag interessieren
            • anwesend sein
            • KEINEN Gesprächstermin zu dieser Uhrzeit haben
            • in KEINEM anderen Vortrag zu dieser Uhrzeit sitzen

            Für die beiden letzten Bedingungen brauche ich die Angabe NULL. Mit einer impliziten Abfrage würde ich genau die nicht bekommen.

            Wie kann ich das machen?

            Kalle

            1. yo,

              Ach so, implizit heisst OHNE Joins ...

              nicht ganz, auch bei der impliziten schreibweise werden letztlich joins gebildet, aber diese joins werden eben nicht explizit in der abfrage hin geschrieben, sondern einfach durch kommas getrennt. das kann zum einen zu einer anderen ausführung kommen und zum anderen wird es viel schwieriger die abfrage zu lesen.

              Das geht in meinem Fall wohl nicht, weil ich eine Negativ- Aussage brauche.

              was immer auch eine negativ-aussage ist, bei dir geht das auch. ich kenne dein design nicht mehr genau, wenn du mir noch mal sagst, was in welcher tabelle steht, da kann ich sie dir herleiten. aber auf den ersten blick würde ich sagen, dass du keine LEFT JOINS brauchst, sondern INNER JOINS zur anwendung kommen können und für deine "negation" mit EXISTS, bzw. NOT EXISTS arbeiten kannst.

              Ilja

              1. Hallo, Ilja,

                ich brauche so eine Aufstellung:

                ADAC:
                Slot Aussteller Besucher
                ---- ---------- --------
                01   Schneider  NULL
                01   Müller     Heitmann
                02   Müller     NULL
                03   Schneider  Kerst
                03   Müller     Lachmann
                ...

                Bedeutung: Der Aussteller ADAC hat zwei Mitarbeiter vor Ort, Schneider und Müller. Die Slot-Nummern zeigen die Anwesenheit an, die NULL- Einträge bei den Besuchern freie Termine, die gebucht werden können.

                Die Aufstellung bekomme ich mit einem Eingangswert: adress_id von Müller (oder Schneider, ist gleichwertig). Zuerst muss ich die Firma von Müller feststellen (per1). Aha, ADAC. Dann die Mitarbeiter vom ADAC (per2). Für jeden Mitarbeiter die Anwesenheit (anw1).

                Die Termine liegen in der Tabelle Kontakte (kon1). Die Kombination Ausstellerperson / Slot ist ein Termin, ein fehlender Eintrag freie Kapazität.

                $q = "
                #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                AUSSTELLER-MITARBEITER ZU ".$chef_id.", UND DEREN TERMINE

                #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                SELECT
                 per1.kurzname
                ,anw1.slot_nr
                ,per2.id
                ,per2.nname
                ,kon1.besucher_id
                FROM
                 ".$db[0]['personen']." as per1
                ,".$db[0]['personen']." as per2
                ,".$db[0]['anwesenheit']." as anw1

                Fehler

                JOIN   ".$db[0]['kontakte']." as kon1
                ON     kon1.aussteller2_id=per2.id AND kon1.slot_nr=anw1.slot_nr

                WHERE  per1.id=".$chef_id."
                AND    per2.owner_id=per1.owner_id AND per2.adr_kz=per1.adr_kz AND per2.kurzname=per1.kurzname
                AND    anw1.adr_id=per2.id
                ORDER BY anw1.slot_nr, per2.id
                ";

                Die Fehlermeldung besagt, dass in der ON- clause per2.id nicht bekannt ist. Wie löse ich das Problem?

                MIt einem Test habe ich mir vorhin noch die Tabelle kontakte zerschossen, sie antwortet nicht mehr.

                LG Kalle