Redundante Datensätze löschen

tklenin

Benutzer
Beiträge
15
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
 
Werbung:
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.
 
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
 
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.
 
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?
 
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)
 
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......
 
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);
 
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.
 
Werbung:
@
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
 
Zurück
Oben