Ja, ich habe eine Idee, sie ist furchtbar technisch , „müsste“ aber funktionieren.
Folgende freie SQL-Abfrage würde in „Kontakte“ (Tabelle heißt „Contacts“) bei allen gefundenen Dubletten jeweils immer 1 „retten“, d.h. ausschließen. Der Trick dahinter ist, dass man in einer weiteren Unterabfrage per TOP 1 nur genau 1 Duplikat liefern lässt (welches das sein wird ist hier willkürlich, über ein order by könnte man noch nach Erfassungsdatum aufsteigend sortieren und hätte immer das älteste) und dieses dann von den Treffern explizit ausschließt und somit „bewahrt“.
Keine Sorge: Sie müssen die SQL-Magie dahinter nicht im Detail verstehen, um sie nutzen zu können.
Das eigentliche Dublettenkriterium ist in dem Beispiel unten: "Name"
und "Firstname"
müssen übereinstimmen, dann sei es eine Dublette (NULL
-Werte und leere Feldinhalte (''
) werden synonym gleich behandelt).
Dieses Kriterium muss identisch an zwei Stellen unten eingefügt werden, einmal bezieht es sich auf "Y"
und einmal auf "Z"
. Siehe unten. Vielleicht es es bei Ihnen die „Artikelnummer“ (aber bitte bei SQL-Abfragen immer den physikalischen Feldnamen nutzen) und sonst nichts anderes, dann ändern Sie das an beiden (!) Stellen identisch ab (einmal mit "Y"
einmal mit "Z"
). Und natürlich ersetzen Sie an allen Stellen "Contacts"
durch Ihren Tabellennamen.
Falls Sie keine Papierkorb-Funktion in der betreffenden Ansicht aktiviert haben, dann müssen Sie die Zeile nach dem „als gelöscht markierte Datensätze generell immer ausschließen:“-Kommentar ersatzlos löschen (zwei Stellen).
SELECT "Contacts"."ID"
FROM "Contacts"
WHERE
(
EXISTS
(
SELECT 'Results!'
FROM "Contacts" "Y"
WHERE
(
"Contacts"."ID" <> "Y"."ID"
AND
(
--Die Dublettenkriterien:
ISNULL("Contacts"."Name",'') = ISNULL("Y"."Name",'') AND ISNULL("Contacts"."Firstname",'') = ISNULL("Y"."Firstname",'')
-- als gelöscht markierte Datensätze generell immer ausschließen:
AND ("Y"."RecycleBinID" IS NULL) AND ("Contacts"."RecycleBinID" IS NULL)
)
AND "Contacts"."ID"
NOT IN
(
SELECT TOP 1 "Z".ID
FROM "Contacts" "Z"
WHERE
(
--Die Dublettenkriterien (identisch zu oben, allerdings auf "Z" bezogen, nicht auf "Y"):
ISNULL("Contacts"."Name",'') = ISNULL("Z"."Name",'') AND ISNULL("Contacts"."Firstname",'') = ISNULL("Z"."Firstname",'')
-- als gelöscht markierte Datensätze generell immer ausschließen:
AND ("Z"."RecycleBinID" IS NULL) AND ("Contacts"."RecycleBinID" IS NULL)
)
-- hier könnte man noch einkommentieren, dass es z.B. immer das älteste Duplikat ist, das erhalten bleiben soll:
-- ORDER BY "Z"."CreatedOn"
)
)))
Tipp: Wenn Sie aus dem (einzigen) NOT IN
oben ein IN
machen, dann erhalten Sie genau die Duplikate, die erhalten bleiben sollen/werden. Das ist ein guter Gegencheck, bevor es „ernst wird“!
Viel Erfolg und nochmaliges Backup nicht vergessen.
Wenn es Probleme gibt, einfach melden.
§§§-Disclaimer: wir haben die Abfrage nur kurz mit ein paar Datensatzkopien rasch gecheckt, wir stellen sie hier „as is“ zur Verfügung, ohne Gewähr und so weiter!