Read: (MySQL) SELECT gleicher Spalteninhalte > 1 mal vorhanden

Hi,

ich hab ein kleines Problem. Das vorhandene Szenario: Ich möchte in meiner Tabelle "members" das Feld "lastip" auf doppelte IP Einträge prüfen. Und sowohl id, als auch lastip auslesen lassen und in ein Array speichern. Bisher hab ich erfolglos folgenden Code zusammen bekommen, welcher mir mit einem foreach leider nur die ID und IP des zweiten von zwei Einträgen mit der selben IP ausgibt, da auch nur ein Datensatz aus der Datenbank ausgelesen wird.

  
    $sql_cuip = $db->Query("SELECT id,lastip FROM " . prefix_nexmin . "members GROUP BY lastip HAVING count(*) > 1");  
  
    $num = $sql_cuip->numrows();  
    $count_numip = $num;  
  
    $cuip_array = array();  
  
    while ($row = $sql_cuip->fetchrow()) {  
        array_push($cuip_array,array(  
                'id' => $row->id,  
                'lastip' => $row->lastip )  
        );  
    }  

Ich bedanke mich schonmal im Voraus für die Hilfe =)

lG Read

  1. Lösung:

      
    sqlite> SELECT id, lastip FROM members m1 WHERE  
       ...>   (SELECT COUNT(*) FROM members m2 WHERE m2.lastip = m1.lastip) > 1;  
    1|1.2.3.4  
    2|1.2.3.4  
    5|3.4.5.6  
    6|3.4.5.6  
    7|3.4.5.6
    

    Ich danke trotzdem jedem, der versucht hatte zu helfen ;)

    lG Read

    1. n'abend,

      sqlite> SELECT id, lastip FROM members m1 WHERE
         ...>   (SELECT COUNT(*) FROM members m2 WHERE m2.lastip = m1.lastip) > 1;

        
      Das ist eine korrellierende Subquery. Das bedeutet, dass die Zweite SELECT-Query für \*jeden Datensatz\* aus der ersten Query ausgeführt wird. Das ist - was die Performance angeht - denkbar schlecht.  
        
      Stell dir vor du fährst mit einem 5 Meter breiten Panzer auf einer 6 Meter breiten Straße zum Einkaufen. Wenn Nachts die Straßen leer sind ist das kein Problem. Aber zur Rush Hour kannst du dein Vorhaben glatt vergessen.  
        
      Schau dir mal an was die Datenbank mit der Query macht. Das EXPLAIN Keyword wird dir weiterhelfen. Da du nicht angegeben hast welches DBMS du einsetzt, kann ich dir auch keinen Link zur entsprechenden Dokumentation geben.  
        
        
      weiterhin schönen abend...
      
      -- 
      #selfhtml hat ein Forum?  
        
      sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
      
  2. n'abend,

    SELECT id,lastip FROM tbl_members GROUP BY lastip HAVING count(*) > 1

    Wo wir wieder bei den Unzulänglichkeiten von MySQL angelangt wären. Prinzipiell sollte diese Query nämlich nicht ausgeführt werden. Das Problem liegt bei der Mischung von gruppierten und ungruppierten Spalten.

    Du könntest in einer Query die doppelten Werte und deren jeweilige Anzahl ermitteln. In einer Zweiten Query sammelst du dann die IDs zu den mehrfach vorkommenden IPs. Das kann eine separate Query sein, oder eine Subquery.

    Ich würde mir - sofern die Datenbank keine Performanceprobleme zeigt - die folgende Query genauer anschauen:

    SELECT t.lastip, m.id  
      FROM ( SELECT lastip, COUNT(*) as weight FROM tbl_members GROUP BY lastip HAVING COUNT(*) > 1 ) as t  
      JOIN tbl_members m  
        ON m.lastip = t.lastip  
     ORDER BY t.weight DESC, lastip;
    

    Dabei betrachten wir das Ergebnis der inneren SELECT-Query als Tabelle, die wir wiederum mit unserer eigentlichen Tabelle verbinden können, um weitere - nicht gruppierte - Daten in unsere Ergebnismenge bringen zu können.

    weiterhin schönen abend...

    --
    #selfhtml hat ein Forum?
    sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|