Frage

Ich habe eine MySQL-Datenbank-Tabelle mit zwei Spalten, die mich interessieren. Individuell können sie jede Duplikate haben, aber sie sollten nie ein Duplikat beide mit dem gleichen Wert haben.

stone_id können Duplikate haben, solange für jeden upsharge Titel unterschiedlich ist, und umgekehrt. Aber sagen wir zum Beispiel stone_id = 412 und upcharge_title = „Saphir“, die Kombination nur einmal vorkommen sollte.

Das ist ok:

stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "ruby"

Das ist nicht ok:

stone_id = 412 upcharge_title = "sapphire"
stone_id = 412 upcharge_title = "sapphire"

Gibt es eine Abfrage, die Duplikate in beiden Feldern finden? Und wenn möglich ist es eine Möglichkeit, meine Daten-Basis einzustellen nicht zulassen?

Ich bin mit MySQL Version 4.1.22

War es hilfreich?

Lösung

Sie sollten einen zusammengesetzten Schlüssel zwischen den beiden Feldern aufgebaut. Dies erfordert eine einzigartige stone_id und upcharge_title für jede Zeile.

Was finden die bestehenden Duplikate versuchen Sie dies:

select   stone_id,
         upcharge_title,
         count(*)
from     your_table
group by stone_id,
         upcharge_title
having   count(*) > 1

Andere Tipps

Ich fand es hilfreich, ein unqiue Index hinzufügen ein „ALTER ignore“ mit denen die Duplikate entfernt und erzwingt eindeutige Datensätze, die so klingt, was Sie tun möchten. So ist die Syntax wäre:

ALTER IGNORE TABLE `table` ADD UNIQUE INDEX(`id`, `another_id`, `one_more_id`);

Dies fügt effektiv die eindeutige Einschränkung bedeutet, dass Sie nie doppelte Datensätze haben und die IGNORE die vorhandenen Duplikate löscht.

Sie können mehr lesen über eh ALTE hier IGNORE: http: // mediakey .dk / ~ cc / mysql-remove-Duplikat-Einträge /

Update: Ich wurde von @Inquisitive darüber informiert, dass diese in MySQL-Versionen fehlschlagen> 5.5:

  

Es kann nicht auf MySQL> 5.5 und auf InnoDB-Tabelle und in Percona wegen   ihre InnoDB schnell Indexerstellung Funktion [ http://bugs.mysql.com/bug. php? id = 40344] . In diesem Fall   erster Lauf set session old_alter_table=1 und dann der obige Befehl   wird funktionieren

Update - ALTER IGNORE Entfernt In 5.7

Von der docs

  

Ab MySQL 5.6.17 wird die Klausel IGNORE veraltet und seine Verwendung   gibt eine Warnung aus. IGNORE entfernt in MySQL 5.7.

Einer der give MySQL dev zwei Alternativen :

  • Gruppe durch die einzigartigen Felder und löschen, wie oben zu sehen
  • Erstellen Sie eine neue Tabelle, fügen Sie einen eindeutigen Index, Verwendung INSERT IGNORE, ex:
CREATE TABLE duplicate_row_table LIKE regular_row_table;
ALTER TABLE duplicate_row_table ADD UNIQUE INDEX (id, another_id);
INSERT IGNORE INTO duplicate_row_table SELECT * FROM regular_row_table;
DROP TABLE regular_row_table;
RENAME TABLE duplicate_row_table TO regular_row_table;

Aber abhängig von der Größe der Tabelle, kann dies nicht praktikabel sein

Sie können Duplikate wie diese finden ..

Select
    stone_id, upcharge_title, count(*)
from 
    particulartable
group by 
    stone_id, upcharge_title
having 
    count(*) > 1

, um die Duplikate zu finden:

select stone_id, upcharge_title from tablename group by stone_id, upcharge_title having count(*)>1

Um beschränkt dies in Zukunft zu vermeiden, um einen zusammengesetzten eindeutigen Schlüssel auf diesen beiden Felder erstellen.

Im übrigen kann ein Verbund eindeutige Einschränkung auf dem Tisch würde dies verhindert in erster Linie auftreten.

ALTER TABLE table
    ADD UNIQUE(stone_id, charge_title)

(Dies gilt T-SQL. Nicht sicher MySQL.)

Diese SO Post mir geholfen, aber ich wollte auch wissen, wie eine der Zeilen zu löschen und hält ... hier ist eine PHP-Lösung der doppelten Zeilen zu löschen und ein hält (in meinem Fall gab es nur zwei Spalten und in einer Funktion ist doppelte Kategorie Verbände für das Clearing)

$dupes = $db->query('select *, count(*) as NUM_DUPES from PRODUCT_CATEGORY_PRODUCT group by fkPRODUCT_CATEGORY_ID, fkPRODUCT_ID having count(*) > 1');
if (!is_array($dupes))
    return true;
foreach ($dupes as $dupe) {
    $db->query('delete from PRODUCT_CATEGORY_PRODUCT where fkPRODUCT_ID = ' . $dupe['fkPRODUCT_ID'] . ' and fkPRODUCT_CATEGORY_ID = ' . $dupe['fkPRODUCT_CATEGORY_ID'] . ' limit ' . ($dupe['NUM_DUPES'] - 1);
}

die (Grenze NUM_DUPES - 1) ist das, was die einzelne Zeile bewahrt ...

Dank all

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top