roadguide: Query um Doubletten in einer DB zu finden und anzuzeigen

Habe mich nun seit Stunden bemueht ( Suchfunktion ) genutzt und auch eine ganze Reihe von Threads zu meinem Problem gefunden. Leider ist es trotzdem nicht gelungen so das ich um Rat fragen muss.

Arbeite mit PHP Version: 5.1.6 und Database Version: 5.0.77.

Moechte ein eigentlich simples Problem loesen, naemlich alle doppelten Eintraege aus meiner Mysql anzeigen lassen, damit diese geprueft werden koennen. Das loeschen erfolgt manuell.

Habe inzwischen eine Reihe von Varianten versucht, aber alle brachten wie auch diese nur EINEN doppelten Eintrag als Ergebniss.

 $query = ' SELECT '.$select_wp.' FROM #__unimap_markers  
             GROUP BY #__unimap_markers.wp_latitude,wp_longitude  
             HAVING COUNT(*) > 1  
                  ';  

Vermutlich brauche ich eine INNER JOIN abfrage, nur gelingt es mir nicht diesen Code so anzupassen das er bei mir laueft.

SELECT A.[Personen-Id] As [Datensatz-ist-Kandidat-zum-Loeschen]  
  
	From tbl_Personen As A INNER JOIN  
  
		(Select X.Nachname, X.Vorname, X.Geburtstag  
			From tbl_Personen As X  
			Group By X.Nachname, X.Vorname, X.Geburtstag  
			Having Count(*) > 1) As B  
  
	On 	A.Nachname = B.Nachname  
		And A.Vorname = B.Vorname  
		And A.Geburtstag = B.Geburtstag

Koennte mir bitte jemand helfen wie saehe der korrekte Query aus um NUR alle mindest 2x vorkommenden Eintraege als Ausgabe zu erhalten.

Der Query muesste auch die Abfrage einer zweiten Tabelle beinhalten, nur wenn ich es soooo mache kommen ganz wirre Ergebnisse heraus.

 $select_wp = " #__unimap_markers.wp_id, wp_cat_id, wp_user_id, wp_title, wp_country, wp_province, wp_city, wp_zip, wp_latitude, wp_longitude, wp_approv_id, wp_editdate, wp_approv_status, wp_website, wp_flagged, wp_published ";  
$select_cat = " #__unimap_cats.cat_id, cat_icon, cat_title, cat_published ";  
  
$query = ' SELECT '.$select_wp.', '.$select_cat.' FROM #__unimap_markers, #__unimap_cats  
             GROUP BY #__unimap_markers.wp_latitude,wp_longitude  
             HAVING COUNT(*) > 1  
                  ';  

~~~  
  1. Hi!

    Du hast ein Datenbankproblem. Sei in deinem eigenen Interesse bitte so zuvorkommend deinen potentiellen Antwortern gegenüber, die PHP-Code-Teile aus dem Problem herauszuhalten, also gleich nachvollziehbaren (koopierbaren) SQL-Code zu liefern. Und dann zeichne bitte auch SQL-Syntax nicht mit lang=php sondern mit lang=sql aus. Danke.

    Moechte ein eigentlich simples Problem loesen, naemlich alle doppelten Eintraege aus meiner Mysql anzeigen lassen, damit diese geprueft werden koennen. Das loeschen erfolgt manuell.

    Die einzige (mir bekannte) Möglichkeit, Dubletten zu finden, ist eine Gruppierung mit anschließendem HAVING COUNT()>1

    Habe inzwischen eine Reihe von Varianten versucht, aber alle brachten wie auch diese nur EINEN doppelten Eintrag als Ergebniss.

    Das "Problem" beim GROUP BY ist, dass es eine Aggregat-Klausel ist, also die gruppierten Einträge zu einem zusammenfasst. Und da dann nicht genau bestimtm werden kann, welcher der Datensätze nun die Daten für die SELECT-Klausel liefern soll, darf man üblicherweise nur die gruppierten Felder und Aggregat-Funktionen in die SELECT-Klausel schreiben. MySQL lässt hier zwar auch andere Felder zu, aber mit ungewissem Ergebnis.

    GROUP_CONCAT() kann zumindest die Werte eines Feld der Gruppe zu einem String zusammenketten. Damit könntest du eine Liste der IDs bekommen, anhand derer du in einem zweiten Schritt die betroffenen Datensätze abfragen kannst.

    Vermutlich brauche ich eine INNER JOIN abfrage, nur gelingt es mir nicht diesen Code so anzupassen das er bei mir laueft.

    Woraus vermutest du das? Wie wurde an der Fundstelle erklärt, was der Trick an speziell dieser Lösung ist?

    SELECT A.[Personen-Id] As [Datensatz-ist-Kandidat-zum-Loeschen]

    From tbl_Personen As A INNER JOIN

      (Select X.Nachname, X.Vorname, X.Geburtstag  
      	From tbl_Personen As X  
      	Group By X.Nachname, X.Vorname, X.Geburtstag  
      	Having Count(*) > 1) As B  
    

    On A.Nachname = B.Nachname
    And A.Vorname = B.Vorname
    And A.Geburtstag = B.Geburtstag

    
    >   
    > Koennte mir bitte jemand helfen wie saehe der korrekte Query aus um NUR alle mindest 2x vorkommenden Eintraege als Ausgabe zu erhalten.  
      
    Sieht doch passabel aus (der Alias X ist überflüssig). Woran scheitert es denn konkret bei dir?  
      
    
    > Der Query muesste auch die Abfrage einer zweiten Tabelle beinhalten, nur wenn ich es soooo mache kommen ganz wirre Ergebnisse heraus.  
    > SELECT ... FROM #\_\_unimap\_markers, #\_\_unimap\_cats  
    >              GROUP BY #\_\_unimap\_markers.wp\_latitude,wp\_longitude  
    >              HAVING COUNT(\*) > 1  
      
    Du hast damit einen Join gebaut, bei dem ein kartesisches Produkt herauskommt, also jeder Datensatz mit jedem verknüpft ist. Wenn du den Sinn erklären würdest, warum du die zweite Tabelle benötigst ...  
      
      
    Lo!
    
    1. Hi!

      Du hast ein Datenbankproblem. Sei in deinem eigenen Interesse bitte so zuvorkommend deinen potentiellen Antwortern gegenüber, die PHP-Code-Teile aus dem Problem herauszuhalten, also gleich nachvollziehbaren (koopierbaren) SQL-Code zu liefern. Und dann zeichne bitte auch SQL-Syntax nicht mit lang=php sondern mit lang=sql aus. Danke.

      Entschuldige das wusste ich nicht. Werde es beherzigen und bedanke mich schonmal fuer die Antwort.

      Ja mit HAVING COUNT()>1 habe ich bereits gearbeitet und dann besagte single Ergebnisse erhalten.

      Die Fundstelle hat es eigentlich gut beschrieben, nur fehlt mir das Wissen an welcher Stelle und in welcher Form, ich nun meine eigenen Variablen in den Code einfuegen muss. Daher bin ich mit dem Inner Join steckengeblieben.

      Was die Sache anbelangt mit der zweiten Tabellenabfrage, die wird benoetigt um weitere Abgleiche der auszulesenden Datenpunkte zu ermoeglichen. Daten der einen werden mit Daten der anderen Tabelle abgeglichen. Der eigentliche Query ist sehr viel umfangreicher als ich ihn hier dargestellt habe.
      Nur der Uebersichtlichkeit halber habe ich mich bei meiner Frage auf das wesentliche beschraenkt und wuerde einen funktionierenden Query dann im zweiten Schritt um den  restlichen Teil selber erweitern.

      Mir wuerde ein Sql Code weiterhelfen, welcher die doppelten Datensaetze anzeigt und nicht in Konflikt mit der zweiten Tabellenabfrage kommt.

      Mit PHP und HMTL komme ich seit Jahren gut zurecht, allerdings bei MYSQl sind meine Kentnisse leider NULL.

      1. Hi!

        Ja mit HAVING COUNT()>1 habe ich bereits gearbeitet und dann besagte single Ergebnisse erhalten.
        Die Fundstelle hat es eigentlich gut beschrieben, nur fehlt mir das Wissen an welcher Stelle und in welcher Form, ich nun meine eigenen Variablen in den Code einfuegen muss. Daher bin ich mit dem Inner Join steckengeblieben.

        Die Abfrage wa eigentlich ziemlich einfach. Die Felder, über die die Dublette erkannt werden, waren Name, Vorname und Geburtsdatum. Die Subquery liefert genau diese Felder und gruppiert auch darüber. Damit berücksichtigt die Abfrage sogar die erwähnten Besonderheiten beim Gruppieren. Und sie liefert wegen der Gruppierung nur jeweils einen Datensatz. Das HAVING schränkt auf mehrfache ein. Verknüpft mit der selben Tabelle (erste Angabe der FROM-Klausel) ermittelt werden nun aus dieser alle Datensätze geliefert, die mit den Feldern der Subquery übereinstimmen.

        Was die Sache anbelangt mit der zweiten Tabellenabfrage, die wird benoetigt um weitere Abgleiche der auszulesenden Datenpunkte zu ermoeglichen. Daten der einen werden mit Daten der anderen Tabelle abgeglichen. Der eigentliche Query ist sehr viel umfangreicher als ich ihn hier dargestellt habe.

        Dann scheint mir, dass du erst einmal die Grundlagen des Verknüpfens kennenlernen musst.

        Mir wuerde ein Sql Code weiterhelfen, welcher die doppelten Datensaetze anzeigt und nicht in Konflikt mit der zweiten Tabellenabfrage kommt.

        Erstell erst einmal die Abfrage der beiden verknüpften Tabellen. Dann kannst du diese Query gemäß dem Muster der Dublettenabfrage verwenden. Wenn dir das Ganze zu unübersichtlich wird - Verknüpfungen und Verschachtlungen - dann kannst du dir ja die verküpfte Abfrage in einer View ablegen. (Ich hoffe, dass das geht, hab ich nämlich bisher noch nicht benötigt).

        Lo!

        1. Hi

          Die Abfrage wa eigentlich ziemlich einfach. Die Felder, über die die Dublette erkannt werden, waren Name, Vorname und Geburtsdatum. Die Subquery liefert genau diese Felder und gruppiert auch darüber. Damit berücksichtigt die Abfrage sogar die erwähnten Besonderheiten beim Gruppieren. Und sie liefert wegen der Gruppierung nur jeweils einen Datensatz. Das HAVING schränkt auf mehrfache ein. Verknüpft mit der selben Tabelle (erste Angabe der FROM-Klausel) ermittelt werden nun aus dieser alle Datensätze geliefert, die mit den Feldern der Subquery übereinstimmen.

          Was die Sache anbelangt mit der zweiten Tabellenabfrage, die wird benoetigt um weitere Abgleiche der auszulesenden Datenpunkte zu ermoeglichen. Daten der einen werden mit Daten der anderen Tabelle abgeglichen. Der eigentliche Query ist sehr viel umfangreicher als ich ihn hier dargestellt habe.

          Dann scheint mir, dass du erst einmal die Grundlagen des Verknüpfens kennenlernen musst.

          Mir wuerde ein Sql Code weiterhelfen, welcher die doppelten Datensaetze anzeigt und nicht in Konflikt mit der zweiten Tabellenabfrage kommt.

          Erstell erst einmal die Abfrage der beiden verknüpften Tabellen. Dann kannst du diese Query gemäß dem Muster der Dublettenabfrage verwenden. Wenn dir das Ganze zu unübersichtlich wird - Verknüpfungen und Verschachtlungen - dann kannst du dir ja die verküpfte Abfrage in einer View ablegen. (Ich hoffe, dass das geht, hab ich nämlich bisher noch nicht benötigt).

          Lo!

          Hier ist der komplette funktionierende Query, so wie er derzeit genutzt wird. Diesen wollte ich eigentlich um die Moeglichkeit erweitern das NUR die Dubletten angezeigt werden und alles uebrige genau wie vorher funktioniert.
          Das war mein Anliegen bei dieser Frage gewesen. Wenn ich wuesste wie man das mit den Vorschlaegen verbinden muss haette ich nicht fragen muessen.
          Was ich brauche ist der vollstaendige, einsatzfaehige Query mit MEINEN Variablen. Wuerde das auch jederzeit bezahlen !! Nur mit den bisherigen Antworten konnten ich rein garnichts anfangen, wenn sie auch gut gemeint waren.

                 $query = ' SELECT '.$select_wp.', '.$select_cat.'  
                            FROM #__unimap_markers, #__unimap_cats  
                            WHERE #__unimap_cats.cat_published > 0  
                            AND #__unimap_cats.cat_user_id = '.$user->id.'  
                            AND #__unimap_markers.wp_cat_id = #__unimap_cats.cat_id '.  
                             $select['wp_id']. $select['wp_cat_id']. $select['wp_title']. $select['wp_user_id']. $select['wp_country']. $select['wp_province'].  
                             $select['wp_city']. $select['wp_zip']. $select['wp_latitude']. $select['wp_longitude']. $select['wp_approv_id']. $select['wp_editdate']. $select['wp_approv_status']. $select['wp_website'].  
                             $select['wp_flagged']. $select['wp_published']. $searchterm. $orderby.'  
                             ';