2009-03-13 9 views
77

Ich habe eine MySQL-Datenbanktabelle mit zwei Spalten, die mich interessieren. Einzeln können sie Duplikate haben, aber sie sollten niemals ein Duplikat von BEIDEN von ihnen haben, die denselben Wert haben.So finden Sie Dubletten in 2 Spalten nicht 1

stone_id können Duplikate haben, solange für jeden upsharge Titel ist anders, und umgekehrt. Aber sagen Sie zum Beispiel stone_id = 412 und upcharge_title = "Saphir", dass diese Kombination nur einmal vorkommen sollte.

Das ist ok:

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

Dieses NICHT in Ordnung ist:

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, gibt es eine Möglichkeit, meine Datenbank darauf einzustellen, das nicht zuzulassen?

Ich bin mit MySQL Version 4.1.22

Antwort

142

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

Was findet die bestehenden Duplikate versuchen Sie dies:

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

Vielen Dank, dass sie nicht wählen. Könnten Sie so freundlich sein, mir zu sagen, wie man Duplikate löscht (aber 1 Kopie natürlich lassen) DANKE !! –

+1

Ein Weg wäre, alle unterschiedlichen Daten zu erfassen und die Tabelle neu zu erstellen. –

+1

@John Isaacks: Wenn es keine anderen Felder gibt, mit denen Sie sie unterscheiden könnten (d. H. Alle Felder sind Duplikate), müssen Sie beide Zeilen löschen und eine neu erstellen. Eine Möglichkeit wäre, Duplikate in eine Kopie der Tabelle zu kopieren, sie aus dem Original zu löschen und verschiedene Zeilen aus der Kopie wieder einzufügen. –

4

die Duplikate zu finden:

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

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

+1

Vielen Dank, können Sie mir bitte sagen, wie Sie alle außer einem der Duplikate löschen können. Und wie richte ich einen Compresseschlüssel in phpmyadmin ein? DANKE!!! –

3

Sie können Duplikate wie diese finden ..

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

übrigens eine zusammengesetzte eindeutige Einschränkung auf den Tisch dies auftritt in erster Linie verhindern würde.

ALTER TABLE table 
    ADD UNIQUE(stone_id, charge_title) 

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

+0

Ich denke, dass funktioniert, aber es lässt mich es nicht tun, bis ich die Duplikate zuerst entferne. Vielen Dank. –

0

diese SO Post half mir, aber ich wollte auch wissen, wie und eine der Zeilen halten löschen ... hier ist eine PHP-Lösung, die die doppelten Zeilen und hält eine (in meinem Fall gibt es nur zwei Spalten, und es ist in einer Funktion zum löschen doppelte Kategorie Verbände)

$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 löschen (Limit NUM_DUPES - 1) ist das, was bewahrt die einreihig ...

danke alle

+3

'ALTER IGNORE TABLE Tabelle ADD UNIQUE INDEX index_name (stone_id, charge_title)' entfernt doppelte Zeilen und hinterlässt nur ein eindeutiges Paar. –

26

Ich fand es hilfreich, einen eindeutigen Index mit einem "ALTER IGNORE" hinzuzufügen, der die Duplikate entfernt und eindeutige Datensätze erzwingt, die sich so anhören, als würden Sie gerne tun. So würde die Syntax sein:

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 löscht die vorhandenen Duplikate.

können Sie mehr lesen über eh ALTE hier IGNORE: http://mediakey.dk/~cc/mysql-remove-duplicate-entries/

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

Es scheitert an MySQL> 5.5 und in InnoDB-Tabelle und in Percona wegen ihre InnoDB schnelle Indexerstellungsfunktion [http://bugs.mysql.com/bug.php?id=40344]. In diesem Fall ersten Lauf set session old_alter_table=1 und dann der obige Befehl wird funktionieren

+0

+1 Nur 3 Jahre zu spät ... aber immer noch nützliche Informationen. Vielen Dank. –

+1

Stimmt, aber zumindest für das nächste Mal wissen Sie. Ich hatte das gleiche Problem und dachte, dass es gut ist, mit anderen zu teilen – SeanDowney

+0

Ich war nur ärgern darüber, dass es 3 Jahre zu spät ist. Freut mich wirklich, dass du es geteilt hast. Daher das Plus 1. –