Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Redundante Datensätze löschen

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von tklenin, 12 August 2016.

  1. tklenin

    tklenin Benutzer

    Hallo Leute,
    habe in MYSQL eine Datenbank, welche mehrere redundante Datensätze enthält und möchte diese gerne bis auf einen verbleibenden löschen. Habe mir dabei ein Listing erstellt, welches mir die Datensätze zunächst ma'
    anzeigt. Das löschen allerdings will mir nicht gelingen. Anhand folgendem Code werden mehr datensätze gelöscht, als erforderlich.
    Weiß jemand Rat? Im Internet erhältliche Listings waren infunktionabel.
    Hier der Code:


    DELETE FROM tabelle USING tabelle, tabelle as tmptabelle
    WHERE NOT tabelle.spalte1=tmptabelle.spalte1
    AND tabelle.spalte1 > tmptabelle.spalte1
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Kannst Du die zu löschenden Datensätze exakt benennen, z.B. via deren PK?
     
  3. ukulele

    ukulele Datenbank-Guru

    Ich verstehe den Sinn hinter deinem Code auch nicht. Wenn tabelle.spalte1 > tmptabelle.spalte1, dann ist tabelle.spalte1 auch zwigend ungleich tmptabelle1.spalte1. Abgesehen davon machst du einen Cross-Join aller Datensätze (eine Join-Condition scheint gar nicht vorhanden) und wunderst dich das vermutlich so gut wie alles die Bedinung erfüllt.

    Erschwerend kann sich MySQL meines Wissens nach bei UPDATE und bei DELETE nicht immer auf die Tabelle selbst beziehen, könnte also auch einen Fehler werfen.
     
  4. tklenin

    tklenin Benutzer

    Kann sie nicht exact benennen. Es sind derer zu viele. Grob gesagt handelt es sich um eine Schachspielerdatenbank, welche ich auf vierSpalten gekürzt habe:
    Name, ELO, Geburtsjahr und Herkunftsland. Die Bruttogröße beträgt etwa 14 MB.
    Anhand folgendem Code wurde mir die Redundanz angezeigt:
    SELECT A.spalte1,A.spalte2…..FROM tabelle AS A GROUP BY A.spalte1,A.spalte2 HAVING COUNT (*)> 1
     
  5. akretschmer

    akretschmer Datenbank-Guru

    falls kein PK drauf ist, dann hast auch keine FKs auf diese Tabelle. Einfach ein select distinct machen in eine zwischentabelle, tabelle löschen, zwischentabelle umbenennen.
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Du sollst sie auch nicht an den 8 Fingern deiner zwei Hände (zwei Finger bei Unfall verloren?) aufzählen, sondern via SQL benennen.
     
  7. tklenin

    tklenin Benutzer

    Nun denn, sofern keine Möglichkeit besteht, auf einfachem Wege via Code die Redundanz zu beseitigen, werde ich halt, wie vorgeschlagen, mittels select distinct eine neue Tabelle anlegen lassen, also in etwas so????:
    CREATE TABLE name_Tabelle_neu AS SELECT DISTINCT (spalte1, spalte2....)FROM name_Tabelle_alt
    Ist das so richtig?
     
  8. akretschmer

    akretschmer Datenbank-Guru

    ja, nur ohne Klammern. Das ist keine Funktion.

    In PostgreSQL kann man für sowas die CTID-Spalte nehmen (eine von mehreren versteckten Spalten eines jeden Datensatzes, vielleicht hat MySQL sogar was ähnliches?)

    Code:
    test=*# select * from dubletten ;
     a | b | c
    ---+---+---
     1 | 2 | 3
     1 | 2 | 3
     1 | 2 | 3
     4 | 5 | 6
     4 | 5 | 6
    (5 Zeilen)
    
    test=*# delete from dubletten where ctid not in (select max(ctid) from dubletten group by a,b,c);
    DELETE 3
    test=*# select * from dubletten ;
     a | b | c
    ---+---+---
     1 | 2 | 3
     4 | 5 | 6
    (2 Zeilen)
    
     
  9. tklenin

    tklenin Benutzer

    Tja, mit PostgreSQL kenne ich mich so gar nicht aus. Auch mit Oracle nicht wirklich.
    Habe mich vor kurzem erst mit MYSQL (phpmyadmin) angefreundet und diverse Testdatenbanken zusammengesucht(plz.SQL, terra.SQL, schach.SQL etc..etc...).
    Hätte rein theoretisch auch mittels php eine Datenbank erzeugen können. Allerdings wären deren Einträge sinnlose Werte gewesen.
    Einen Algorithmus, der Datenbanken mit sinnigen string-arrays füllt, gibt es wohl nicht........
    Beende hiermit diesen Thread als erfolgreich abgeschlossen und bedanke mich für Dein rasches Feedback.
    Salut......
     
  10. akretschmer

    akretschmer Datenbank-Guru

    ?
     
  11. BerndB

    BerndB Datenbank-Guru

    IGNORE is yout friend.

    Du kannst einfach eine UNIQUE INDEX die die Spalte anlegen.
    Dieser würde normalerweise einen DUPLICATE KEY error auswerfen, jedoch mit dem Zusatz IGNORE löscht er dir sofort die Duplikate. Diesen KEY kannst du nachher lassen oder wieder löschen

    Code:
    ALTER IGNORE TABLE YourTable add unique key idx_dup
    (column1,column2,column3,column4,column5);
     
  12. akretschmer

    akretschmer Datenbank-Guru

    nach welchen Regeln werden da Zeilen gelöscht? Also, falls da noch weitere Spalten sind, auf die sich der unique nicht bezieht?
     
  13. akretschmer

    akretschmer Datenbank-Guru

    Um meine Frage zu beantworten: die erste gefundene Zeile bleibt wohl erhalten, die anderen werden gelöscht. Da 'die erste gefundene Zeile' bei Datenbanken eher zufällig ist wird also ganz offenbar hier auch ganz zufällig irgend was gelöscht. Tolle Wurst. Offenbar hat man dies aber erkannt, und seit 5.7.4 (also mitten in der 5.7 - Reihe) wird dieses tolle Feature ignoriert - spricht, IGNORE gibt es da nicht mehr. Ein weiteres schönes Beispiel für MySQL-Murks.
     
  14. BerndB

    BerndB Datenbank-Guru

    @
    akretschmer - Laut Doku kann man das nicht sagen. Ich habe mir das aber für InnoDB im Source-Code angesehen und dabei hangelt er sich bei Aufbau der neuen Index am PK durch un lässt immer den ersten, also wenn die Fehlermeldung Duplikate käme löscht er den Record. Für andere Engines kann ich das leider nicht sagen
     
    akretschmer gefällt das.
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden