1

Ich habe die folgende Tabelle bekam verwendet, um Benutzer zu verfolgen, die ein Support-Ticket beobachtenMySQL Downgrading Composite-Primärschlüssel restriktiver sein

CREATE TABLE IF NOT EXISTS crm_ticketwatcher (
    ticketid int(10) unsigned NOT NULL DEFAULT '0', 
    employeeid int(10) unsigned NOT NULL DEFAULT '0', 
    contactid int(10) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (ticketid,employeeid,contactid) 
) ENGINE=MyISAM; 

Ich möchte eine Herabstufung Skript haben, die contactid aus dem Primärschlüssel entfernt .

Der Tabelleninhalt sieht ein bisschen wie dieses

ticketid|employeeid|contactid 
--------|----------|--------- 
5  |5   |0 
5  |8   |0 
5  |0   |2 
5  |0   |3 

Als ich (erfolglos) herabzustufen Skript ausführen,

ALTER TABLE crm_ticketwatcher DROP PRIMARY KEY, ADD PRIMARY KEY (ticketid, employeeid);

ich die folgende Fehlermeldung erhalten:

ERROR 1062 (23000) at line 1: Duplicate entry '306-0' for key 'PRIMARY'

, weil es jetzt zwei Zeilen mit dem Primärschlüssel-Set (5, 0)

Was ist der beste Weg, um die zusätzlichen Zeilen aus der Tabelle zu löschen, Speichern des letzten vorkommenden?

Wir sind auf MySQL 5.7.13, so das Schlüsselwort IGNORE ist keine Option.

Danke.

+0

können Sie mir sagen, auch die Struktur der Tabelle, die Sie Informationen erhalten „auftreten dauern“? wie Datum. Oder möchten Sie nur die höchste oder niedrigste Kontaktreihe behalten? Welchen halten Sie (5, 0, 2) oder (5, 0, 3)? – Tin

+0

(5, 0, 3) gehalten werden würde, weil es die unterste Reihe –

+0

ist soll ich denke eggyal Antwort für diesen Fall arbeiten. – Tin

Antwort

0

Wie unter ALTER TABLE Syntax dokumentiert:

IGNORE is a MySQL extension to standard SQL. It controls how ALTER TABLE works if there are duplicates on unique keys in the new table or if warnings occur when strict mode is enabled. If IGNORE is not specified, the copy is aborted and rolled back if duplicate-key errors occur. If IGNORE is specified, only one row is used of rows with duplicates on a unique key. The other conflicting rows are deleted. Incorrect values are truncated to the closest matching acceptable value.

Daher können Sie tun:

ALTER IGNORE TABLE crm_ticketwatcher 
    DROP PRIMARY KEY, 
    ADD PRIMARY KEY (ticketid, employeeid); 

ist jedoch zu beachten, dass die von den "Duplikat" Zeilen erhalten bleibt unbestimmt sein.

Wenn Sie ein bestimmtes Ergebnis möchten, oder verwenden MySQL v5.7.4 und höher (von denen IGNORE entfernt wurde), können Sie zunächst eine führen Selbstverknüpfung mit der Multiple-Table DELETE Syntax:

DELETE c1 
FROM crm_ticketwatcher c1 
    JOIN crm_ticketwatcher c2 USING (ticketid, employeeid) 
WHERE c1.contactid < c2.contactid -- or whatever logic you prefer 
+0

Ich habe einen Fehler damit und fand dies auf der MySQL-Dokumentation Seite 'Ab MySQL 5.7.4, die IGNORE-Klausel für ALTER TABLE entfernt und seine Verwendung erzeugt einen Fehler. ' –

+0

@GavinGassmann: Und zur Vermeidung von Zweifel, verwenden Sie eine Version von MySQL ≥5.7.4? – eggyal

+0

Ja, ich werde die Version auch dem OP hinzufügen. –