UDATE statt INSERT wenn doppelter Eintrag

Nehmen wir folgenden Fall an: Ich habe eine Tabelle mit verschiedenen Werten.

CREATE TABLE `xyz` (  
    `a` VARCHAR(50) NOT NULL,  
    `b` INT(10) NOT NULL DEFAULT '0',  
    `c` DATETIME NOT NULL
);

Bisher wurden die Werte wild hinzugefügt oder geändert.

INSERT INTO `xyz` (`a` ,`b` ,`c`) VALUES ('Testeintrag', '123', NOW());
oder
UPDATE `xyz` SET `a`='Testeintrag',`c`=NOW() WHERE b='123';

Jetzt aber möchte ich dieser Tabelle etwas hinzufügen – aber nur dann – wenn der Wert in Spalte b nicht existiert. Andernfalls muss der Eintrag geändert werden. Dieses Konstrukt über die Applikationslogik(en) abzubilden, wäre in meinem Fall aber recht aufwändig gewesen. Deshalb musste eine andere Lösung her.

MySQL bietet in diesem Fall eine einfache Lösung an INSERT … ON DUPLICATE KEY UPDATE. Hierzu muss die entscheidende Spalte b als UNIQUE definiert werden (Hinweis: Doppelte Eintrage in MySQL Tabelle finden) und die Query in der Applikation wie folgt angepasst werden.

INSERT INTO `xyz` (`a` ,`b` ,`c`) VALUES ('Testeintrag', '123', NOW())
ON DUPLICATE KEY UPDATE `a`='Testeintrag',`c`=NOW();

Wenn jetzt der Wert der Spalte b bereits in der Tabelle enthalten ist, wird diese Spalte einfach aktualisiert.

Weitere Informationen zum Thema:
http://dev.mysql.com/doc/refman/5.1/de/insert-on-duplicate.html

Doppelte Einträge in MySQL Tabelle finden

Ich denke der Titel verrät bereits um was es in diesem Artikel geht. Ausgangspunkt ist folgende Tabelle.

CREATE TABLE `xyz` (
    `a` VARCHAR(50) NOT NULL,
    `b` INT(10) NOT NULL DEFAULT '0',
    `c` DATETIME NOT NULL
);

Nun soll die Spalte b einen UNIQUE Key bekommen. Das Problem ist aber, das es in dieser Spalte bereits viele Dopplungen gibt. Um sie zu finden nehme ich folgende Abfrage.

SELECT `b` FROM `xyz` WHERE `b` 
IN (
   SELECT `b` 
   FROM `xyz` 
   GROUP BY `b` 
   HAVING Count( 1 ) >1
);

Die Abfrage zeigt mir jetzt alle Einträge der Spalte b die mehr als einmal vorkommen. Jetzt kann man die Einträge entweder manuell bereinigen oder die SELECT Abfrage in eine DELETE Abfrage umbauen. Fertig.