hawkmaster: Doppelte Einträge auflisten

Hallo zusammen,

in einer Tabelle "kunden" gibt es doppelte Einträge.

kundenid, kundename, kundennummer
1,        ABC GmbH,  123
2,        ABC GmbH,  123

Mit dieser Abfrage kann ich zwar alle doppelten Einträge ermitteln:

  
SELECT kundenname, kundennummer, COUNT(*) AS Anzahl  
FROM kunden  
GROUP BY kundenname, kundennummer  
HAVING COUNT(*) > 1  

Ich bräuchte aber nicht die Anzahl 2 oder 3 sondern ich bräuchte alle betroffenen Datensätze mit kundenid ausgegeben.

Ich habe es schon mal mit einem Subselect versucht, aber nicht hinbekommen.

Danke für jede Anregung.

Gruss
hawk

vielen Dank und viele Grüße
hawk

  1. Om nah hoo pez nyeetz, hawkmaster!

    Danke für jede Anregung.

    Ich rege an, einen Selfjoin zu verwenden.

    Matthias

    --
    Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Gummi und Gummibärchen.

    1. Hallo Mattias,

      danke für deine Anregung:
      vielleicht habe ich das auch falsch verstanden mit dem InnerJoin.
      Wenn ich es so versuche:

        
      SELECT  
          KK1.kundenid,  
          KK1.kundenname,  
          KK1.kundennummer  
        
      FROM  
          kunde KK1  
      INNER JOIN  
          kunde KK2  
      ON  
          KK1.kundenname = KK2.kundenname  
      INNER JOIN  
          kunde KK3  
      ON  
          KK1.kundennummer = KK3.kundennummer  
      
      

      bekomme ich ja eher mehr Einträge angezeigt als es in der original Tabelle sind.

      vielen Dank und viele Grüße
      hawk

      1. Om nah hoo pez nyeetz, hawkmaster!

        SELECT
            KK1.kundenid,
            KK1.kundenname,
            KK1.kundennummer

        FROM
            kunde KK1
        INNER JOIN
            kunde KK2
        ON
            KK1.kundenname = KK2.kundenname
        INNER JOIN
            kunde KK3
        ON
            KK1.kundennummer = KK3.kundennummer

          
        ~~~sql
        SELECT  
          k1.kundenid,  
          k1.kundenname,  
          k2.kundenname  
        FROM  
          kundentabelle k1  
        INNER JOIN  
          kundentabelle k2  
        ON  
          k1.kundenname = k2.kundenname
        

        Ungetestet

        Matthias

        --
        Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Otto und Ottomane.

        1. Hallo Mattias,

          SELECT

          k1.kundenid,
            k1.kundenname,
            k2.kundenname
          FROM
            kundentabelle k1
          INNER JOIN
            kundentabelle k2
          ON
            k1.kundenname = k2.kundenname

          
          >   
          > Ungetestet  
            
          Leider nein, so hatte ich es zuerst versucht.  
          Bringt aber als Ausgabe 700 Datensätze obwohl nur 660 drin sind.  
          Zudem muss ich ja auch noch die kundenummer vergleichen weil ich ja nur die Einträge finden will, wo kundenname UND kundenummer identisch sind.  
            
          vielen Dank und viele Grüße  
          hawk
          
      2. Hi,

        Hallo Mattias,

        danke für deine Anregung:
        vielleicht habe ich das auch falsch verstanden mit dem InnerJoin.
        Wenn ich es so versuche:

        SELECT
            KK1.kundenid,
            KK1.kundenname,
            KK1.kundennummer

        FROM
            kunde KK1
        INNER JOIN
            kunde KK2
        ON
            KK1.kundenname = KK2.kundenname
        INNER JOIN
            kunde KK3
        ON
            KK1.kundennummer = KK3.kundennummer

        
        >   
        > bekomme ich ja eher mehr Einträge angezeigt als es in der original Tabelle sind.  
          
        Du mußt natürlich noch ausschließen, daß kk1.id = kk2.id ist.  
          
        Und warum bringst Du kk3 noch ins Spiel?  
          
        cu,  
        Andreas
        
        -- 
        [Warum nennt sich Andreas hier MudGuard?](http://MudGuard.de/)  
        [O o ostern ...](http://ostereier.andreas-waechter.de/)  
          
        Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.  
        
        
        1. Hallo Andreas,

          danke dir auch.

          Und warum bringst Du kk3 noch ins Spiel?

          ich dachte man braucht das weil ich ja den kundennamen UND die kundennummer auf Gleichheit überprüfen muss und nicht nur den Namen.

          vielen Dank und viele Grüße
          hawk

  2. Tach!

    Mit dieser Abfrage kann ich zwar alle doppelten Einträge ermitteln:

    SELECT kundenname, kundennummer, COUNT(*) AS Anzahl

    FROM kunden
    GROUP BY kundenname, kundennummer
    HAVING COUNT(*) > 1

    
    > Ich bräuchte aber nicht die Anzahl 2 oder 3 sondern ich bräuchte alle betroffenen Datensätze mit kundenid ausgegeben.  
    > Ich habe es schon mal mit einem Subselect versucht, aber nicht hinbekommen.  
      
    Anhand eines nicht gezeigten Versuchs kann ich dir nicht sagen, wo der Fehler steckt. Du kannst aber das obige Statement als Subquery nehmen, wenn du kundenname und COUNT(\*) aus der SELECT-Liste nimmst, also nur kundennummer drinlässt. Diese Subquery kannst du in ein WHERE kundennummer IN (subquery) stecken.  
      
      
    dedlfix.
    
    1. Tach!

      GROUP BY kundenname, kundennummer
      Du kannst aber das obige Statement als Subquery nehmen, wenn du kundenname und COUNT(*) aus der SELECT-Liste nimmst, also nur kundennummer drinlässt.

      Achso, kundenname ist sicher auch noch im GROUP BY überflüssig. Anhand der Nummer sollten schon Duolikate zu erkennen sein. Jedenfalls sollten Kundennummern nicht mehreren Kunden zugewiesen sein. Aber vielleicht hast du ja auch einen anderen Anwendungsfall, als ich mir grad vorstelle.

      dedlfix.

    2. Hallo dedlfix,

      danke für deine Hilfe.

      Also die Abfrage

        
      SELECT kundenname, kundennummer, COUNT(*) AS Anzahl  
      FROM kunden  
      GROUP BY kundenname, kundennummer  
      HAVING COUNT(*) > 1  
      
      

      bringt mir schon das gewünschte Ergebnis.
      Und ich muss schon kundename und kundennummer ins Group By aufnehmen weil ich ja nur die Einträge finden will, wo kundenname UND kundennummer identisch ist.

      weil es kann ja auch Einträge geben wo der gleiche Kundename vorkommt, aber die Kundennumer anders ist

      kundenid, kundename, kundennummer
      1,        ABC GmbH,  123
      2,        ABC GmbH,  123
      3,        ABC GmbH,  4711

      Meine gewünschte Abfrage soll aber nur die Einträge

      1,        ABC GmbH,  123
      2,        ABC GmbH,  123

      finden, und zwar mit kundenid.

      vielen Dank und viele Grüße
      hawk

      1. Tach!

        Und ich muss schon kundename und kundennummer ins Group By aufnehmen weil ich ja nur die Einträge finden will, wo kundenname UND kundennummer identisch ist.

        Gut, dann kann das im GROUP BY drinbleiben. Die Kunden-IDs bekommst du aber so nicht, sondern nur eine zufällige aus der jeweiligen Gruppe, wenn du die mit ins SELECT nähmest (MySQL-only). Wenn es dir nur darum geht, sie überhaupt zu bekommen, dann wäre GROUP_CONCAT() eine Lösung, das gibt sie dir kommasepariert - und das ganz ohne Subquery. Wenn du sie zwecks Weiterverarbeitung getrennt brauchst, dann geht nur die Subquery-Lösung (oder eine andere mit gleichem Ergebnis). DIe kann dir aber nur einen Wert zurückliefern, weenn du sie im WHERE verwenden willst. Eine andere Möglichkeit wäre, sie in der FROM-Klausel zu nehmen und dann beide Werte (Name und Nummer) in der Join-Bedingung miteinander zu vergleichen.

        dedlfix.

  3. Hallo zusammen,

    ich habe das mit den Subsulect noch nicht hinbekommen.
    Mal angenommen es geht rein um den Select der Einträge und das nachträgliche Anzeigen OHNE doppelte Kundennamen- Kundennummer Kombination.

    Ein einfacher:

    SELECT DISTINCT kundename, kundenummer  FROM kunde;

    würde ja das ja auch schon ausfiltern. Aber auch hier habe ich wieder das Problem das ich die Spalte "kundenid" nicht im Select habe. Wenn ich diese in den DISTINCT mit aufnehme, klappt ja dieser nicht mehr, da die kundenid ja immer unterschiedlich ist.

    vielen Dank und viele Grüße
    hawk

    1. Tach!

      Mal angenommen es geht rein um den Select der Einträge und das nachträgliche Anzeigen OHNE doppelte Kundennamen- Kundennummer Kombination.
      Ein einfacher:
      SELECT DISTINCT kundename, kundenummer  FROM kunde;
      würde ja das ja auch schon ausfiltern. Aber auch hier habe ich wieder das Problem das ich die Spalte "kundenid" nicht im Select habe.

      Ja, das ist das generelle Problem bei Gruppierungen, unter die auch das DISTINCT gewissermaßen fällt. Da werden mehrere Datensätze zu einem zusammengefasst. In deinem Fall hast du nun zwei oder mehr kundenid, die nicht in eine Ergebniszeile gepresst werden können. Du kannst da nur Aggregatfunktionen wie MIN(), MAX(), SUM(), AVG(), etc. darauf anwenden. Aber das ist im Falle der kundenid ja sinnlos. GROUP_CONCAT() ist da erstmal die einzige sinnvolle Möglichkeit.

      ich habe das mit den Subsulect noch nicht hinbekommen.

      Ich habs jetzt nicht probiert, aber sollte nicht sowas zum Erfolg führen?

      SELECT *  
      FROM kunden,  
      (SELECT kundenname, kundennummer  
      FROM kunden  
      GROUP BY kundenname, kundennummer  
      HAVING COUNT(*) > 1) kunden2  
      WHERE kunden.kundenname = kunden2.kundenname AND kunden.kundennummer = kunden2.kundennummer
      

      dedlfix.

      1. Hallo dedlfix,

        sorry für die späte Rückmeldung. Ich bin jetzt erst zum ausprobieren gekommen.

        Ich habs jetzt nicht probiert, aber sollte nicht sowas zum Erfolg führen?

        SELECT *

        FROM kunden,
        (SELECT kundenname, kundennummer
        FROM kunden
        GROUP BY kundenname, kundennummer
        HAVING COUNT(*) > 1) kunden2
        WHERE kunden.kundenname = kunden2.kundenname AND kunden.kundennummer = kunden2.kundennummer

        
        >   
          
        Das ist genau das was ich brauchte oder wie ich es mir vorgestellt hatte.  
        Mir war nur diese Schreibweise oder Gebrauch von Subselect nicht bekannt.  
        Ich hatte bisher einen Subselect nur in der Form benutzt:  
          
        SELECT `MyID` FROM `myTable` WHERE MyIDNOT IN(  
        SELECT MyID FROM `myTable.....  
          
          
        vielen Dank und viele Grüße  
        hawk
        
  4. Hallo zusammen,
    Danke für jede Anregung.

    Um die 1000 Records? Das würde ich händisch bereinigen und mir überlegen, was als Kriterium für konsistente Daten in Frage käme (Kundenname oder Kunden-ID) und wie ich die Konsistenz der Daten nachhaltig sicherstelle, bspw. mit einem unique key auf die Kunden-ID (der Name könnte sich ja ändern, aus Baucke Sen. wird Baucke Nachf.).

    Guck Dir die Tabelle an, sortiert nach Kundenname, sortiert nach Kunden-ID und möglicherweise besteht der erste Schritt zur Bereinigung darin, einen unique key auf die Kunden-ID zu setzen (alter table ... es kommt eine Rückfrage... bestätigen).

    MfG

    1. Hallo

      Es wurde eigentlich schon verhindert, dass es bei der Einabe von Kundenname und Kundennummer keine doppelten Einträge geben darf. Wenn dies der Fall war, wurde der vorhandene Kundeneintrag genommen.

      Es gab aber eine Situation:
      Eingabe etwa:

      Kundename     Kundenummer
      -------------------------------------
      Kunde 1 GmbH  1234
      Kunde 1 GmbH  4711

      In dem Fall wurden ja beide Einträge gespeichert, da unterschiedliche Kundenummer.
      Wenn nun nachträglich der Eintrag mit Kundennummer 4711 auf 1234 geändert wurde, gab es identische Einträge. Dies wurde bisher nicht geprüft oder verhindert da nicht gewünscht.

      Das könnte (müsste) man jetzt eigentlich verhindern. Sei es durch Unique Keys oder gleich beim Speichern und Prüfung durch PHP

      vielen Dank und viele Grüße
      hawk

      1. Hallo

        Es wurde eigentlich schon verhindert, dass es bei der Einabe von Kundenname und Kundennummer keine doppelten Einträge geben darf.

        Anders formuliert: Es wurden doppelte Einträge erzwungen. :-)

        Tschö, Auge

        --
        Verschiedene Glocken läuteten in der Stadt, und jede von ihnen vertrat eine ganz persönliche Meinung darüber, wann es Mitternacht war.
        Terry Pratchett, "Wachen! Wachen!"
        ie:{ fl:| br:> va:) ls:[ fo:) rl:( ss:| de:> js:| zu:}
        Veranstaltungsdatenbank Vdb 0.3