C. Hackert: Doppelte Einträge löschen

moin leute,

ich betreibe eine datenbank, in der etwa 1700 einträge sind und täglich werden es mehr. da sich die leute selbst eintragen können, sind teilweise einträge doppelt.

am anfang war es kein problem, per hand die datenbank zu durchsuchen - mittlerweile wird sie dazu allerdings zu groß...

von daher nun meine frage, ob es eine elegante methode gibt, die datenbank zu durchsuchen und doppelte einträge zu löschen?

ich habe es bereits mit folgenem versucht, war aber leider alles vergebens...:

$query ="SELECT url FROM websites ORDER BY url";
$result = mysql_query($query);
$number = mysql_numrows($result);
if ($number == 0) php_die ("keine Urls!");

for($i=0; $i < $number; $i++){

$row = mysql_fetch_array($result);
   $url = $row[url];
   $query2 ="SELECT url FROM websites WHERE (url like '%$url%') ORDER BY url";
   $result2 = mysql_query($query2);
   $number2 = mysql_numrows($result2);
   if ($number2 == 0) php_die ("keine doppelten Urls!");

for($j=0; $j < $number2; $j++){

$row2 = mysql_fetch_array($result2);

  1. hab noch zwei sachen vergessen:

    würde mich über jeden tip freuen und schon mal vielen dank im voraus!

    Christian Hackert

  2. Hallo Christian,

    von daher nun meine frage, ob es eine elegante methode gibt, die datenbank zu durchsuchen und doppelte einträge zu löschen?

    die Frage hat zwar eher was mit SQL als mit PHP direkt zu tun,
    daher habe ich Dir mal ein Beispiel erstellt:

    SELECT * INTO tblTemp FROM <tabelle> WHERE <tabelle>.<feld> IN
    (SELECT <feld> FROM <tabelle> GROUP BY <feld> HAVING COUNT(<feld>) > 1)
    AND <tabelle>.<idfeld> > (SELECT min(<idfeld>) FROM <tabelle>);

    Zur Erklärung:
    <tabelle> - Der Name Deiner Tabelle
    <feld> - Feld, in dem doppelte Werte vorkommen können
    <idfeld> - Unique Key der Zeile (muss vorhanden sein)

    Damit erzeugst Du eine temp. Tabelle, die alle doppelten Zeilen der Originaltabelle beinhaltet. (Abfrage der mehrfach vorkommenden Werte in Spalte <feld>)
    Durch die Angabe:
    AND <tabelle>.<idfeld> > (SELECT min(<idfeld>) FROM <tabelle>);
    wird der erste Satz, der mit diesem Wert angelegt wurde, nicht in
    tblTemp eingetragen, da Du da bestimmt einen behalten willst.

    Nun setzt Du noch ein Delete auf die Originaltabelle ab und fertig.
    DELETE FROM <tabelle> WHERE <idfeld> IN (SELECT <idfeld> FROM tblTemp);

    Evtl. noch die temp. Tabelle löschen:
    DROP TABLE tblTemp;

    Allerdings übernehme ich keinerlei Garantie, dass das auf MySQL
    funktioniert. Und Du solltest auf jeden Fall vorher eine Sicherungskopie
    der Datenbank anlegen.
    Für Schreib- Syntax- und alle sonst irgendwie möglichen Fehler
    wird keine Garantie übernommen.
    Wenn alles klappt, gehört der Code mir und jeder der ihn liest, muss
    Lizenzgebühren wegen evtl. Verwendung in anderen Projekten zahlen :-))

    Tschau, Stefan

    1. moin stefan,

      mit den "Lizenzgebühren" wird wahrscheinlich nichts - mysql versteht select * into leider nicht...:(

      aber trozdem danke für deine hilfe! du hast mich auf eine neue idee gebracht

      keep on :-)
      c.hackert