Duplikate löschen und den richtigen Datensatz behalten
Definieren Sie fachliche Duplikate und eine eindeutige Gewinnerregel, prüfen Sie ROW_NUMBER und verhindern Sie erneute Duplikate.
Beim Entfernen von Duplikaten ist DELETE selten der schwierige Teil. Schwieriger sind die fachliche Identität, die zu erhaltenden Informationen und gültige Referenzen. Gleiche E-Mail-Adressen beweisen nicht dieselbe Person. Auch der höchste Identity-Wert bezeichnet nicht automatisch den vertrauenswürdigsten Datensatz.
Gleichheit und Gewinner festlegen
Formulieren Sie den Duplikatschlüssel als fachliche Regel. Berücksichtigen Sie Mandant und Quellsystem. Legen Sie die Bedeutung von Großschreibung, Akzenten, Leerzeichen und fehlenden Werten fest. SQL-Server-Vergleiche folgen der Kollation. Das Zusammenfassen von NULL kann falsch sein, wenn NULL eine unbekannte statt einer gemeinsamen Identität bedeutet.
Definieren Sie eine deterministische Gewinnerregel. Im Beispiel bilden TenantId und ExternalKey den Geschäftsschlüssel. Die zuletzt beobachtete Zeile gewinnt; RowId löst gleiche Zeitstempel eindeutig auf. Ohne diesen letzten eindeutigen Vergleich könnten verschiedene Ausführungen unterschiedliche Gewinner wählen.
Fehlende ExternalKey-Werte werden bewusst ausgeschlossen. Unbekannte Datensätze bleiben unabhängig, bis ein anderer Abstimmungsprozess sie zuordnet. Das ist eine mögliche fachliche Entscheidung und keine universelle Bedeutung von NULL.
CREATE TABLE #CustomerStage
(RowId int PRIMARY KEY, TenantId int NOT NULL,
ExternalKey varchar(20) NULL, SeenAt datetime2(0) NOT NULL);
INSERT #CustomerStage VALUES
(1,1,'A','2020-01-01'),(2,1,'A','2020-02-01'),
(3,2,'A','2020-01-01'),(4,1,NULL,'2020-01-01'),
(5,1,NULL,'2020-02-01');
;WITH ranked AS
( SELECT *, ROW_NUMBER() OVER
(PARTITION BY TenantId, ExternalKey
ORDER BY SeenAt DESC, RowId DESC) AS rn
FROM #CustomerStage WHERE ExternalKey IS NOT NULL )
SELECT * FROM ranked WHERE rn > 1 ORDER BY RowId;
Erwartet wird RowId 1 als Löschkandidat. RowId 2 ist neuer für Mandant 1 und Schlüssel A. RowId 3 gehört zu einem anderen Mandanten; 4 und 5 besitzen unbekannte Identität. Besprechen Sie genau diese Ergebnisse vor einer echten Änderung.
Auswahl und Ausführung kontrollieren
Die Löschung eignet sich als Übung, weil sie nur die temporäre Tabelle verändert und anschließend zurückrollt. OUTPUT erfasst die tatsächlich entfernten Zeilen. Nach ROLLBACK sind die ursprünglichen Daten wieder vorhanden. Übertragen Sie das Verfahren erst nach Prüfung von Regel, Umfang, Wiederherstellung und Schreibkonkurrenz auf echte Tabellen.
BEGIN TRAN;
;WITH ranked AS
( SELECT *, ROW_NUMBER() OVER
(PARTITION BY TenantId, ExternalKey
ORDER BY SeenAt DESC, RowId DESC) AS rn
FROM #CustomerStage WHERE ExternalKey IS NOT NULL )
DELETE FROM ranked
OUTPUT deleted.RowId, deleted.TenantId, deleted.ExternalKey
WHERE rn > 1;
ROLLBACK;
Eine Stunden zuvor ausgeführte Vorschau garantiert nicht denselben späteren Löschumfang. Neue Zeilen und geänderte Zeitstempel können den Gewinner verschieben. Nutzen Sie ein kontrolliertes Wartungsfenster oder ein bewusstes Isolationskonzept für Auswahl, Referenzmigration, Löschung und Eindeutigkeitsschutz. Große serialisierbare Transaktionen können erheblich blockieren und sind keine kostenlose Standardlösung.
Ermitteln Sie vor dem Löschen alle referenzierenden Fremdschlüssel sowie Beziehungen ohne deklarierte Constraints. Verweisen Kinder auf doppelte Identitäten, erstellen Sie eine Zuordnung von Verlierer zu Gewinner und übertragen Sie Referenzen nach fachlichen Regeln. Dabei können Kinder an eigenen eindeutigen Schlüsseln kollidieren. Das erfordert eine Entscheidung; abgeschaltete Constraints verdecken nur das Problem.
Informationen behalten und Wiederholung verhindern
Die neuere Zeile kann eine leere Adresse enthalten, während die ältere eine geprüfte Adresse besitzt. Dann verliert eine einfache Gewinnerauswahl wertvolle Information. Konsolidieren Sie Felder nach dokumentierten Vorrangregeln und behalten Sie erforderliche Herkunftsinformationen. Der Gewinner muss nicht unverändert aus einer ursprünglichen Zeile bestehen.
Bewahren Sie eine nachvollziehbare Zuordnung und genügend entfernte Daten für den vereinbarten Wiederherstellungszeitraum auf. Ein Backup ist wichtig, kann nach weiteren legitimen Änderungen aber unhandlich für die gezielte Wiederherstellung einzelner Beziehungen sein. Die Wiederherstellungsinformation sollte ursprüngliche Schlüssel und Transformation enthalten und personenbezogene Daten angemessen schützen.
Erzwingen Sie anschließend die tatsächliche Eindeutigkeitsregel durch einen passenden Constraint oder gefilterten eindeutigen Index. Der Schutz muss zur Behandlung unbekannter Schlüssel passen. Beheben Sie zusätzlich das Rennen beim Import oder die fehlende Idempotenzprüfung. Prüfen Sie Mandantenzahlen, verbleibende Werte, Kinderreferenzen und die Wiederholung des problematischen Imports. Erfolg bedeutet, bestätigte Duplikate zu entfernen, Informationen zu erhalten und das nächste Duplikat unmittelbar abzuweisen.
Technische Referenzen: Microsoft Learn: ROW_NUMBER · Microsoft Learn: Unique indexes.