Gerd: MySql Abfrage über 2 Tabellen mit having

Hallo,

ich habe trotz Suche leider nichts passendes gefunden. Daher nun hier meine bitte um Hilfe.
Ich habe 2 Tabellen (standorte und daten). Mit einer Umkreissuche hole ich mir sämtliche relevanten Standorte aus der Tabelle Standorte:

  
SELECT *, ( 6368 * SQRT(2*(1-cos(RADIANS(breit)) * cos(0.88907776995895) * (sin(RADIANS(lang)) * sin(0.12164247348349) + cos(RADIANS(lang)) * cos(0.12164247348349)) - sin(RADIANS(breit)) * sin(0.88907776995895)))) AS Distance FROM standorte Having (Distance <= 10) ORDER BY Distance  

Das funktioniert auch soweit. Nun möchte ich aus der Tabelle daten die Daten mit der jeweils entsprechenden id abfragen - leider ergebnislos. Mein Ansatz:

  
SELECT *, ( 6368 * SQRT(2*(1-cos(RADIANS(breit)) * cos(0.88907776995895) * (sin(RADIANS(lang)) * sin(0.12164247348349) + cos(RADIANS(lang)) * cos(0.12164247348349)) - sin(RADIANS(breit)) * sin(0.88907776995895)))) AS Distance FROM standorte LEFT JOIN daten ON daten.id=standorte.id Having (Distance <= 10) ORDER BY Distance  

Freue mich über jede Hilfe und jeden Tipp

Gerd

  1. Tach,

    SELECT , ( 6368 * SQRT(2(1-cos(RADIANS(breit)) * cos(0.88907776995895) * (sin(RADIANS(lang)) * sin(0.12164247348349) + cos(RADIANS(lang)) * cos(0.12164247348349)) - sin(RADIANS(breit)) * sin(0.88907776995895)))) AS Distance FROM standorte Having (Distance <= 10) ORDER BY Distance

      
    gibt es einen Grund warum du HAVING statt WHERE verwendest, obwohl es keine Gruppierung gibt?  
      
    
    > ~~~php
      
    
    > SELECT *, ( 6368 * SQRT(2*(1-cos(RADIANS(breit)) * cos(0.88907776995895) * (sin(RADIANS(lang)) * sin(0.12164247348349) + cos(RADIANS(lang)) * cos(0.12164247348349)) - sin(RADIANS(breit)) * sin(0.88907776995895)))) AS Distance FROM standorte LEFT JOIN daten ON daten.id=standorte.id Having (Distance <= 10) ORDER BY Distance  
    > 
    
    

    Die IDs der Daten und die IDs der Standorte sollen übereinstimmen, klingt mir nicht nach einem üblichen Datenbankschema.

    mfg
    Woodfighter

    1. Hallo,

      ich verwende HAVING weil es so funktionier. Habe mir wohl nicht ausrechende Gedanken dazu gemacht. Die id sind in diesem Fall so etwas wie Kundennummern und sind identisch.

      Beste Grüße

      Gerd

      1. Tach,

        Die id sind in diesem Fall so etwas wie Kundennummern und sind identisch.

        dann machst du etwas falsch, was ich so nicht sehen kann, Tabelledefinitionen und Beispieldaten würden vielleicht mehr Licht ins dunkle bringen.

        mfg
        Woodfighter

        1. Hallo,

          in der Tabelle standorte sind die folgenden Daten:

          user_id (27365)
          plz (10785)
          ort (Berlin)
          breit (52.5069)
          lang (13.3650)

          Tabelle daten:

          user_id (27365)
          name (Hans)
          Nich (HansWurst)
          hobby (Fußball)
          beruf (Maurer)

          Nun kann ich mit Hilfe der folgenden Abfrage (Umkreissuche Berlin 10 km) die entsprechenden Daten aus der Tabelle standorte ausgeben:

            
          SELECT *, ( 6368 * SQRT(2*(1-cos(RADIANS(breit)) * cos(0.88907776995895) * (sin(RADIANS(lang)) * sin(0.12164247348349) + cos(RADIANS(lang)) * cos(0.12164247348349)) - sin(RADIANS(breit)) * sin(0.88907776995895)))) AS Distance FROM standorte Having (Distance <= 10) ORDER BY Distance  
          
          

          In eine while Schleife kann ich mir alle relevanten Daten aus der Tabelle standorte so ausgeben.
          Nun möchte ich anhand der user_id auch die Daten aus der Tabelle daten abfragen.

          Ich hoffe du verstehst was ich meine.

          Danke

          Gerd

          1. Tach,

            in der Tabelle standorte sind die folgenden Daten:

            user_id (27365)
            plz (10785)
            ort (Berlin)
            breit (52.5069)
            lang (13.3650)

            Tabelle daten:

            user_id (27365)
            name (Hans)
            Nich (HansWurst)
            hobby (Fußball)
            beruf (Maurer)

            mit den Testdaten und einer kleinen Anpassung deines Scripts, es gibt keine Spalten id in diesen Tabellen und die Distance ist größer als 10
            SELECT *, ( 6368 * SQRT(2*(1-cos(RADIANS(breit)) * cos(0.88907776995895) * (sin(RADIANS(lang)) * sin(0.12164247348349) + cos(RADIANS(lang)) * cos(0.12164247348349)) - sin(RADIANS(breit)) * sin(0.88907776995895)))) AS Distance FROM standorte LEFT JOIN daten ON daten.user_id=standorte.user_id having (Distance >= 473) ORDER BY Distance;
            bekomme ich genau einen Datensatz als Antwort, wie erwartet ==> du machst etwas anderes falsch.

            mfg
            Woodfighter

            1. Hallo und vielen Dank für deine Mühe und Geduld,

              aber leider komme ich nicht weiter. Ich möchte noch einen Versuch unternehmen.
              Mit diesen Daten Frage ich die Tabelle standorte ab:

                
              ...  
              $_GET['area'] = "10"; # Kommt natürlich vom Formular  
              $_GET['loc'] = "koeln" # Kommt natürlich vom Formular  
                
                
              $query = "SELECT *, (".$radius." * SQRT(2*(1-cos(RADIANS(breit)) * cos(".$rad_b.") * (sin(RADIANS(lang)) * sin(".$rad_l.") + cos(RADIANS(lang)) * cos(".$rad_l.")) - sin(RADIANS(breit)) * sin(".$rad_b.")))) AS Distance  
              FROM standorte having Distance <= ".$_GET['area']." ";  
                
              $select = mysql_query($query);  
              while ($ausgabe=mysql_fetch_object($select))  
              {  
              echo "$ausgabe->plz $ausgabe->ort";  
              # 50678 Köln => das ist richtig und kommt aus der Tabelle standorte  
              }  
              
              

              Ergänze ich den Query um "LEFT JOIN daten ON daten.user_id=standorte.user_id" erfolgt keine Ausgabe:

                
              ...  
              $_GET['area'] = "10"; # Kommt natürlich vom Formular  
              $_GET['loc'] = "koeln" # Kommt natürlich vom Formular  
                
                
              $query = "SELECT *, (".$radius." * SQRT(2*(1-cos(RADIANS(breit)) * cos(".$rad_b.") * (sin(RADIANS(lang)) * sin(".$rad_l.") + cos(RADIANS(lang)) * cos(".$rad_l.")) - sin(RADIANS(breit)) * sin(".$rad_b.")))) AS Distance  
              FROM standorte LEFT JOIN daten ON daten.user_id=standorte.user_id having Distance <= ".$_GET['area']." ";  
                
              $select = mysql_query($query);  
              while ($ausgabe=mysql_fetch_object($select))  
              {  
              echo "$ausgabe->plz $ausgabe->ort";  
              # keine Ausgabe  
              }  
              
              

              Ich müsste doch über die $ausgabe sämtliche daten ausgeben können, aus beiden Tabellen...

              Viele Grüße

              Gerd

              1. Tach,

                ...
                $_GET['area'] = "10"; # Kommt natürlich vom Formular
                $_GET['loc'] = "koeln" # Kommt natürlich vom Formular

                $query = "SELECT , (".$radius." * SQRT(2(1-cos(RADIANS(breit)) * cos(".$rad_b.") * (sin(RADIANS(lang)) * sin(".$rad_l.") + cos(RADIANS(lang)) * cos(".$rad_l.")) - sin(RADIANS(breit)) * sin(".$rad_b.")))) AS Distance
                FROM standorte LEFT JOIN daten ON daten.user_id=standorte.user_id having Distance <= ".$_GET['area']." ";

                $select = mysql_query($query);
                while ($ausgabe=mysql_fetch_object($select))
                {
                echo "$ausgabe->plz $ausgabe->ort";

                keine Ausgabe

                }

                  
                Punkt 1: Ganz wichtig, sofort [den Artikel über Kontextwechsel](http://wiki.selfhtml.org/wiki/Artikel:Kontextwechsel) lesen und umsetzen, du hast hier SQL-Injection-Lücken.  
                  
                Punkt 2: Ich sehe keine Fehlerbehandlung, wo stellst du fest, ob du mit deiner Abfrage ein leeres Ergebnis oder einen Fehler erzeugt hast?  
                  
                Punkt 3: Der Code ist nicht vollständig, da einige Variablendeklarationen fehlen, aber lass dir den Inhalt von $query ausgeben und führe diese direkt auf der Datenbank aus.  
                  
                mfg  
                Woodfighter
                
                1. Hallo Woodfighter,

                  zu Punkt 1 hast du recht. Ich werde das auch alles fixen sobald ich die Grundfunktion habe.
                  Ich habe den Query in der Datenbank ausgeführt: #1052 - Column 'breit' in field list is ambiguous.

                  Werde wahnsinnig

                  Gerd

                  1. Nochmals Hallo,

                    ich habe den Fehler dank deiner Hilfe gefunden.
                    In beiden Tabellen waren die Felder "breit" und "lang" enthalten.

                    Vielen Dank und schönes Wochenende

                    Gerd

    2. Tach!

      SELECT , ( 6368 * SQRT(2(1-cos(RADIANS(breit)) * cos(0.88907776995895) * (sin(RADIANS(lang)) * sin(0.12164247348349) + cos(RADIANS(lang)) * cos(0.12164247348349)) - sin(RADIANS(breit)) * sin(0.88907776995895)))) AS Distance

      FROM standorte
      Having (Distance <= 10)
      ORDER BY Distance

      
      > gibt es einen Grund warum du HAVING statt WHERE verwendest, obwohl es keine Gruppierung gibt?  
        
      Er hat in der SELECT-Klausel eine Berechnung mit dem Alias Distance drin. Diese Berechnung kann man nicht mit WHERE auswerten, weil die WHERE-Filterung vor der SELECT-Berechnung stattfindet. HAVING kommt erst nach der SLECT-Berechnung an die Reihe und kann sich auch auf dort ermittelte Ergebnisse beziehen. Having muss (zumindest bei MySQL) auch nicht zwingend mit GROUP BY einhergehen. Wollte man die Bedingung in WHERE auswerten, müsste man die komplette Formel dort nochmal notieren.  
        
        
      dedlfix.
      
      1. Tach,

        Er hat in der SELECT-Klausel eine Berechnung mit dem Alias Distance drin. Diese Berechnung kann man nicht mit WHERE auswerten, weil die WHERE-Filterung vor der SELECT-Berechnung stattfindet. HAVING kommt erst nach der SLECT-Berechnung an die Reihe und kann sich auch auf dort ermittelte Ergebnisse beziehen. Having muss (zumindest bei MySQL) auch nicht zwingend mit GROUP BY einhergehen. Wollte man die Bedingung in WHERE auswerten, müsste man die komplette Formel dort nochmal notieren.

        äh ja natürlich, danke dir.

        mfg
        Woodfighter