kalle: mysql join?

hey : )

ich hab da mal ne frage zu mysql.

ich lasse momentan dies tun:

ich frage dies ab:

SELECT var1, var2 FROM table1 ORDER BY var2 DESC LIMIT 0,30

und gehe dann jedes ergebnis durch und starte diese abfrage (zu jedem ergebniss)

SELECT var3 FROM table2 WHERE xyz1 <= var1 AND xyz2 >= var1

Hier und da Lese ich etwas über z.B. JOIN() - jedoch werde ich aus der dokumentation nicht schlauer.

wie kann ich diese beiden abfragen zu einer zusammen fügen?

lg, Kalle

  1. Hallo

    ich hab da mal ne frage zu mysql.

    SELECT var1, var2 FROM table1 ORDER BY var2 DESC LIMIT 0,30

    und gehe dann jedes ergebnis durch und starte diese abfrage (zu jedem ergebniss)
    SELECT var3 FROM table2 WHERE xyz1 <= var1 AND xyz2 >= var1

    Hier und da Lese ich etwas über z.B. JOIN() - jedoch werde ich aus der dokumentation nicht schlauer.

    Du verwechselst das mit JOIN.

    Da Du keine Gleichheitsbedingungen hast, somit ein Thetajoin vorliegt, kann Dein JOIN Performance kosten, sollte aber immer noch schneller sein als Deine vielen Einzelabfragen:

    SELECT  
        t1.var1,          -- Spalte var1 aus der Tabelle table1, die hier t1 genannt wird (Alias)  
        t1.var2,          -- analog Spalte var2 aus table1  
        t2.var3           -- Spalte var3 aus table2  
    FROM table1 t1        -- Aliasnamen sparen Schreibarbeit  
    INNER JOIN table2 t2  -- explizite JOIN-Syntax, plus Aliasname  
    ON t2.xyz1 <= t1.var1 AND t2.xyz >= t1.var1  -- JOIN-Bedingung  
    ORDER BY t1.var2 DESC  
    LIMIT 0, 30 
    

    Das kann selbst MySQL 3.23 :-)

    Freundliche Grüße

    Vinzenz

    1. Vielen dank Vinzenz!

      Ich hatte gehofft (ohne nachzudenken) das ich jetzt auf meine zweite abfrage ganz leicht kommt - schaffe ich aber nicht.

      die abfrage ist an sich die gleiche nur kommt möchte ich diesmal noch etwas zählen, nach etwas anderem sortieren und ein anderes limit setzten.

      also ich habe tabelle1 mit t1.var1.
      ich möchte aus tabelle2 die t2.var2 absteigend sortieren (nach vorkommen)
      wo t2.xyz1 <= t1.var1 AND t2.xyz >= t1.var1 ist.

      also das ergebniss sollte dann so aussehen:

      eins     50
      zwei     39
      drei     11

      wobei eins, zwei drei der inhalt von t2.var2 ist.

      ich habe es so probiert aber komme nur 100000 fehler bei raus:

      SELECT
          t1.var1,
          COUNT(t2.var2) AS var3
      FROM table1 t1
      INNER JOIN table2 t2
      ON t2.xyz1 <= t1.var1 AND t2.xyz >= t1.var1
      ORDER BY var3 DESC

      und wie kann ich die anzahl der zurückgegebenen var2s beschränken.
      also das er z.b bei

      neuzehn  60
      zwanzig  44

      schluss macht?

      1. yo,

        möchte ich diesmal noch etwas zählen, nach etwas anderem sortieren und ein anderes limit setzten.

        versuch doch bitte ein wenig mehr zeit in deine fragen zu investieren, dann kann dir auch schneller geholfen werden.

        • was genau willst du zählen ?
        • wonach genau willst du sortieren ?
        • was willst du begrenzen, die anzahl der datensätze, die zurück gegeben werden oder nur bestimmte werte mit in die abfrage nehmen ?

        die lösung für die abfrage slebst erscheint mir trivial zu sein, nur was genau du machen willst verräst du uns nur in kleinen häppchen.

        Ilja

        1. ok,

          ich habe tabelle "visits" ein mit einer spalte "ip_long"
          ich habe eine weitere tabelle "data" mit den spalten "from", "to" und "country".

          ich möchte eine statistik über die anzahl der countries in visits.

          ich habe als ne menge "ip_long" daten und möchte nun in "data" gucken welches "country" auf diesen zahlenbereich zutrifft (data.from <= ip_long AND data.to >= ip_long).

          ich möchte am ende sehen wie oft country (x) in "visits" vorgekommen ist und dieses ergebniss
          (1) absteigend nach häufigkeit sortieren und
          (2) nur die häufigsten (ersten) 30 länder anzeigen lassen.

          Visits Tabelle:
          'ip_long'
          10001
          30001
          50001
          50002

          Daten Tabelle:
          'from'   'to'    'country'
          10000    20000    deutschland
          30000    40000    schweden
          50000    60000    russland

          Und das Ergebniss soll dann so aussehen:
          Russland      2
          Schweden      1
          Deutschland   1

          nur das er bei nur z.b. die ersten 20 länder anzeigt und nicht alle vorhandenen.

          ich hoffe das ist verständlicher : /

          1. yo,

            das ist viel verständlich und damit kann dir auch weiter geholfen werden.

            SELECT country, COUNT(*) AS Anzahl
            FROM visits v
            INNER JOIN data d ON v.ip-long BEWTEEN d.from AND d.to
            GROUP BY d.country
            ORDER BY Anzahl DESC
            LIMIT 0,30

            wobei das LIMIT mit vorsicht zu genießen ist, da natürlich länder mit genau der gleichen anzahl hiervon ausgeschlossen werden können, wenn sie alle auf den 30. platz wären, bzw. davor, wenn es genügend mit den gleichen wert gibt. wenn dir das aber so reicht, kannst du sie verwenden, willst du diesen sonderfall noch mit abdecken, muss du das in einer unterabfrage abfangen und das geht bei mysql dann erst ab 4.1+

            Ilja

            1. Hallo Ilja,

              eine kleine Korrektur:

              INNER JOIN data d ON v.ip-long BEWTEEN d.from AND d.to

              INNER JOIN data d ON v.ip-long BEWTEEN d.from AND d.to``

              Ich persönlich vermeide die Verwendung von reservierten Namen wie from und to zur Bezeichnung von Spaltennamen (oder ähnlichem). Gleiches gilt für Operatoren wie das Minuszeichen :-)

              Freundliche Grüße

              Vinzenz

              1. yo Vinz,

                erstaunlich, wie auffällig unaufällig ich die beiden reservierten wörter einfach als "normale" spaltennamen abgetan habe. sollte mir zu denken gebe, zumal ich diese beiden wörter jeden tag mindestens 100 mal als reservierte wörter benutze. selbstzweifel kommen auf....

                Ilja

              2. das waren auch nur abgekürzte namen.
                bei mir heißen die spalten und tabellen anders : )

                lg, kalle

            2. super dufte!

              das mit dem LIMIT habe ich mir auch schon vorher überlegt, jedoch spiel das keine rolle bei mir.

              trotz deiner klasse abfrage kam es zu einem fehler in dieser zeile:
              ON v.ip_long BEWTEEN i.ip_from AND i.ip_to

              ich habe es dann durch
              ON i.ip_from <= v.ip_long AND i.ip_to >= v.ip_long

              ersetzt und dann klappt es : )

              wobei deine lösung viel sauberer aussieht...

              danke dir!

              1. yo,

                trotz deiner klasse abfrage kam es zu einem fehler in dieser zeile:
                ON v.ip_long BEWTEEN i.ip_from AND i.ip_to

                würde mich mal interessieren, welche fehlermeldung kommt. grundsätzlich ist der BETWEEN Operator wesentlich übersichlicher und deswegen vorzuziehen. kann sein, dass es nicht in der ON klausel stehen kann. dann könntest du die bedingung in die where klausel mit rein nehmen.

                Ilja

                1. yo,

                  habe den fehler schon gefunden, mal mal aus BEWTEEN --> BETWEEN

                  war also nur ein tippfehler....

                  Ilja