Christian: doppelte Einträge löschen

Guten Abend allerseits.

Ich brauche eine PHP-Datei, die doppelte Einträge in meiner MySQL-Tabelle löscht.

$query = "SELECT id,datum_ts,vorname,nachname,addresse FROM Tabelle WHERE 1";
$result = mysql_query($query);
while($row = mysql_fetch_object($result))
 {
 $query = "DELETE FROM Tabelle WHERE ((id != '$row->id') AND (datum_ts = '$row->datum_ts') AND (vorname = '$row->vorname') AND (nachname = '$row->nachname') AND (addresse = '$row->addresse'))";
 mysql_query($query) or die(mysql_error());
 }

Zu meiner Verwunderung wurden alle Einträge gelöscht (also sowohl 'Original' als auch 'Klon'). Ich dachte, " WHERE ((id != '$row->id') " würde dafür sorgen, dass das 'Original' nicht auch mitgelöscht wird.

Ich hab das ganze mal auf Folgendes reduziert:

$query = "SELECT id FROM Tabelle WHERE 1";
$result = mysql_query($query);
while($row = mysql_fetch_object($result))
 {
 $query = "DELETE FROM Tabelle WHERE ((id != '$row->id')";
 mysql_query($query) or die(mysql_error());
 }

Hiermit wurde die Tabelle geleert.

Anscheinend funktioniert das ganze mit der while-Schleife nicht so, wie ich mir das immer vorgestellt hab.
Wenn beim ersten Durchgang alle Datensätze bis auf den ersten gelöscht werden, kann die Schleife doch gar keinen zweiten Durchgang machen?! Was ist denn die zweite ID, die sich von der ersten unterscheiden muss, damit diese gelöscht werden kann?

Ich versteh das nicht und bitte um Rat!

Gute Nacht,
Christian

  1. Zu meiner Verwunderung wurden alle Einträge gelöscht (also sowohl 'Original' als auch 'Klon'). Ich dachte, " WHERE ((id != '$row->id') " würde dafür sorgen, dass das 'Original' nicht auch mitgelöscht wird.

    != ist PHP:

    http://dev.mysql.com/doc/mysql/de/Comparison_Operators.html
    http://dev.mysql.com/doc/mysql/de/Logical_Operators.html

    1. Hallo Heizer,

      != ist PHP:

      Oh ja, stimmt. War mir nie aufgefallen, da es ja auch so funktioniert.

      MfG
      Christian

      1. Hi,

        != ist PHP:
        Oh ja, stimmt. War mir nie aufgefallen, da es ja auch so funktioniert.

        MySQL erlaubt sowohl != als auch <>

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
  2. Hi,

    $query = "SELECT id FROM Tabelle WHERE 1";

    Wozu das WHERE 1? Auch ohne WHERE 1 werden alle Datensätze ausgewählt.

    $result = mysql_query($query);

    $result enthält jetzt alle Datensätze.
    Bsp: die Tabelle enthält Datensätze mit den IDs 1, 2, 3.

    while($row = mysql_fetch_object($result))
    {
    $query = "DELETE FROM Tabelle WHERE ((id != '$row->id')";

    1. Schleifendurchlauf, id = 1.
    Es werden die Datensätze mit den ids 2 und 3 gelöscht.

    2. Schleifendurchlauf, id = 2.
    Es wird der Datensatz mit der id 1 gelöscht (die anderen sind ja schon weg).

    3. Schleifendurchlauf, id = 3.
    Es wird kein Datensatz gelöscht, da bereits nach dem zweiten Durchlauf alle Datensätze gelöscht wurden.

    mysql_query($query) or die(mysql_error());
    }
    Hiermit wurde die Tabelle geleert.

    Ähnliches passiert bei komplizierterer Bedingung (alle Spalten identisch außer der id).
    Annahme: die Datensätze 1 und 3 sind identisch (bis auf die id).

    1. Schleifendurchgang: id = 1.
    Es wird der Datensatz mit der id 3 in der Datenbank als identisch zu Datensatz 1 aus dem $result gefunden und gelöscht.

    2. Schleifendurchgang, id = 2.
    Es wird kein Duplikat gefunden, also nichts gelöscht.

    3. Schleifendurchgang: id = 3.
    Es wird der Datensatz mit der id 1 in der Datenbank als identisch zu Datensatz 3 aus dem $result (der in der Datenbank schon nicht mehr existiert) gefunden und gelöscht.

    Es bleibt Datensatz 2 übrig.

    Mein Vorschlag:
    Laß Dir anfangs die Datensätze sortiert aufsteigend nach der ID ausgeben.
    Dann löschst Du nicht alle Datensätze mit id ungleich row->id, sondern nur die mit id größer row->id.
    Damit sollte von allen Mehrfach-Datensätzen der mit der niedrigsten id übrigbleiben.

    Normalerweise sollte aber bereits beim Eintragen der Daten verhindert werden, daß es zu Doubletten kommt.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. Hi Andreas,

      Wozu das WHERE 1? Auch ohne WHERE 1 werden alle Datensätze ausgewählt.

      Weiß nicht, dachte, das wäre besser, weil phpmyadmin das immer benutzt

      $result enthält jetzt alle Datensätze.

      Achso, richtig, das hatte ich nicht bedacht.

      Dankeschön für die ausführliche Erläuterung.

      Mein Vorschlag:
      Laß Dir anfangs die Datensätze sortiert aufsteigend nach der ID ausgeben.

      Ok, so ähnlich werde ich es machen.

      Normalerweise sollte aber bereits beim Eintragen der Daten verhindert werden, daß es zu Doubletten kommt.

      Richtig. Aber in diesem Fall ist das etwas komplizierter. Es handelt sich nicht wirkliche Doubletten, die das Problem sind, sondern sie unterscheiden sich meist irgendwo, sind jedoch trotzdem doppelt. Beim Auslesen und Importieren der Doppelten kann noch nicht entschieden werden, ob eine der beiden gelöscht werden darf.

      MfG
      Christian

      1. Hallo Christian,

        Wozu das WHERE 1? Auch ohne WHERE 1 werden alle Datensätze ausgewählt.
        Weiß nicht, dachte, das wäre besser, weil phpmyadmin das immer benutzt

        phpmyadmin verwendet das »WHERE 1« um gefahrlos weitere Bedingungen dranhängen zu können - das heißt aber nicht, dass es notwendig ist.

        Grüße aus Nürnberg
        Tobias