it-swarm.com.de

Was ist der beste Weg, um einen Tisch zu entlegen?

Ich habe dafür ein paar Lösungen gesehen, aber ich frage mich, was der beste und effizienteste Weg ist, einen Tisch zu dupemen. Sie können Code (SQL usw.) verwenden, um Ihren Standpunkt zu veranschaulichen, aber ich suche nur nach grundlegenden Algorithmen. Ich nahm an, dass es bereits eine Frage zu SO geben würde, aber ich konnte keine finden. Wenn es also schon existiert, dann geben Sie mir einfach einen Hinweis.

(Nur zur Klarstellung - ich beziehe mich darauf, Duplikate in einer Tabelle zu beseitigen, die eine inkrementelle automatische PK hat und einige Zeilen, die in allem außer dem PK-Feld dupliziert sind.)

28
froadie

SELECT DISTINCT <insert all columns but the PK here> FROM foo. Erstellen Sie eine temporäre Tabelle mit dieser Abfrage (die Syntax variiert je nach RDBMS, normalerweise ist jedoch ein SELECT … INTO- oder CREATE TABLE AS-Muster verfügbar), blasen Sie die alte Tabelle weg und pumpen Sie die Daten aus der temporären Tabelle zurück.

11
Hank Gay

Verwendung der analytischen Funktion Reihennummer:

WITH CTE (col1, col2, dupcnt)
AS
(
SELECT col1, col2,
ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col1) AS dupcnt
FROM Youtable
)
DELETE
FROM CTE
WHERE dupcnt > 1
GO                                                                 
8
Katherine

Deduping ist selten einfach. Dies liegt daran, dass die Datensätze, für die ein Datenaustausch durchgeführt werden soll, häufig etwas andere Werte haben. Daher kann es problematisch sein, zu wählen, welcher Datensatz aufbewahrt werden soll. Außerdem sind Dups häufig Personendatensätze und es ist schwer zu erkennen, ob es sich bei den beiden John Smiths um zwei Personen oder um eine Person handelt, die doppelt vorhanden ist. Also verbringen Sie viel Zeit (50% oder mehr des gesamten Projekts) Ihrer Zeit damit, zu definieren, was einen Dup ausmacht und wie mit den Unterschieden und untergeordneten Datensätzen umzugehen ist. 

Woher wissen Sie, welcher Wert der richtige ist? Für das weitere Dedupping müssen Sie alle untergeordneten Datensätze behandeln, die keine verwaisten. Was passiert, wenn Sie feststellen, dass durch das Ändern der ID im untergeordneten Datensatz plötzlich einer der eindeutigen Indizes oder Einschränkungen verletzt wird, wird dies letztendlich geschehen und Ihr Prozess muss damit umgehen. Wenn Sie sich dumm entschieden haben, alle Einschränkungen nur für die Anwendung anzuwenden, wissen Sie möglicherweise nicht einmal, dass die Einschränkungen verletzt werden. Wenn Sie 10.000 Datensätze für die Deduplizierung haben, werden Sie die Anwendung nicht einzeln durchgehen lassen. Wenn die Einschränkung nicht in der Datenbank enthalten ist, wird beim Datenabgleich mit großer Wahrscheinlichkeit die Datenintegrität gewahrt.

Eine weitere Komplikation ist, dass Dups nicht immer genau mit dem Namen oder der Adresse übereinstimmen. Ein Vertriebsmitarbeiter namens Joan Martin kann beispielsweise ein Vertreter eines Vertriebsmitarbeiters Joan Martin-Jones sein, insbesondere wenn er dieselbe Adresse und E-Mail-Adresse hat. OR Sie könnten John oder Johnny im Namen haben. Oder dieselbe Straßenadresse mit Ausnahme eines Datensatzes, der als ST abgekürzt wird. und eine formulierte Street. In SQL Server können Sie SSIS und Fuzzy-Gruppierung verwenden, um auch nahe Übereinstimmungen zu identifizieren. Dies sind oft die häufigsten Dups, da die Tatsache, dass es keine exakten Übereinstimmungen gab, der Grund ist, warum sie als Dups eingesetzt wurden.

Bei einigen Arten von Dedupping benötigen Sie möglicherweise eine Benutzeroberfläche, damit die Person, die Dedupping ausführt, auswählen kann, welche der beiden Werte für ein bestimmtes Feld verwendet werden soll. Dies gilt insbesondere, wenn die Person, die entlassen wird, zwei oder mehr Rollen hat. Es kann sein, dass die Daten für eine bestimmte Rolle normalerweise besser sind als die Daten für eine andere Rolle. Oder es kann sein, dass nur die Benutzer sicher wissen, welcher Wert der richtige Wert ist, oder dass sie sich mit den Personen in Verbindung setzen müssen, um herauszufinden, ob sie wirklich Dups sind oder nur zwei Personen mit demselben Namen. 

6
HLGEM

Fügen Sie hier den tatsächlichen Code hinzu, um später darauf zurückgreifen zu können 

Es gibt also 3 Schritte und somit 3 SQL-Anweisungen:

Schritt 1: Verschieben Sie die Nicht-Duplikate (eindeutige Tupel) in eine temporäre Tabelle

CREATE TABLE new_table as
SELECT * FROM old_table WHERE 1 GROUP BY [column to remove duplicates by];

Schritt 2: Löschen Sie die alte Tabelle (oder benennen Sie sie um) Die Tabelle mit allen doppelten Einträgen wird nicht mehr benötigt, also löschen Sie sie!

DROP TABLE old_table;

Schritt 3: Benennen Sie die neue_Tabelle in den Namen der alten_Tabelle um

RENAME TABLE new_table TO old_table;

Vergessen Sie natürlich nicht, Ihren fehlerhaften Code zu reparieren, um das Einfügen von Duplikaten zu stoppen!

6
DropHit

Hier ist die Methode, die ich verwende, wenn Sie Ihre Dupe-Kriterien durch Anweisung in eine Gruppe bringen können und Ihre Tabelle eine ID-Identitätsspalte für die Eindeutigkeit enthält:

delete t
from tablename t
inner join  
(
    select date_time, min(id) as min_id
    from tablename
    group by date_time
    having count(*) > 1
) t2 on t.date_time = t2.date_time
where t.id > t2.min_id

In diesem Beispiel ist date_time das Gruppierungskriterium. Wenn Sie mehr als eine Spalte haben, stellen Sie sicher, dass Sie allen beitreten.

3
DShook

Ich nehme das von DShook und gebe ein Deduplizierungsbeispiel, in dem Sie nur die Aufzeichnung mit dem höchsten Datum aufbewahren würden. 

In diesem Beispiel sagen wir, ich habe 3 Datensätze, die alle dieselbe app_id haben, und ich möchte nur den Datensatz mit dem höchsten Datum beibehalten:

DELETE t
FROM @USER_OUTBOX_APPS t
INNER JOIN  
(
    SELECT 
         app_id
        ,max(processed_date) as max_processed_date
    FROM @USER_OUTBOX_APPS
    GROUP BY app_id
    HAVING count(*) > 1
) t2 on 
    t.app_id = t2.app_id
WHERE 
    t.processed_date < t2.max_processed_date
2
Taylor Brown

Für diejenigen, die einen schnellen und schmutzigen Ansatz bevorzugen, listen Sie einfach alle Spalten auf, die zusammen einen eindeutigen Datensatz definieren, und erstellen Sie einen eindeutigen Index mit diesen Spalten.

ALTER IGNORE TABLE TABLE_NAME ADD UNIQUE (column1, column2, column3)

Sie können die eindeutigen Indexnachwörter löschen.

1
Demian Perry

Dies kann die doppelten Werte in c1 entkopplung:

select * from foo
minus
select f1.* from foo f1, foo f2
where f1.c1 = f2.c1 and f1.c2 > f2.c2
0
Jim X.

Sie können für jede Zeile einen Hash erstellen (mit Ausnahme des PK), in einer neuen Spalte speichern (oder, wenn Sie keine neuen Spalten hinzufügen können, können Sie die Tabelle in einen temporären Bereitstellungsbereich verschieben?) Und dann nach allen anderen suchen Zeilen mit demselben Hash. Natürlich müssten Sie sicherstellen können, dass Ihre Hash-Funktion nicht denselben Code für verschiedene Zeilen erzeugt.

Wenn zwei Reihen doppelt sind, spielt es dann eine Rolle, welche Sie loswerden? Ist es möglich, dass andere Daten von beiden Duplikaten abhängig sind? Wenn ja, müssen Sie einige Schritte durchlaufen:

  • Finde die Dupes
  • Wählen Sie eine davon als dupeA aus, um sie zu entfernen
  • Finden Sie alle Daten abhängig von dupeA
  • Ändern Sie diese Daten, um auf dupeB zu verweisen.
  • dupeA löschen.

Dies kann je nach vorhandenem Datenmodell einfach oder kompliziert sein.

Dieses ganze Szenario klingt nach einem Wartungs- und Redesignprojekt. Wenn ja, viel Glück !!

Für SQL können Sie die INSERT IGNORE INTO-Tabelle SELECT xy FROM unkeyed_table verwenden.

Wenn Sie für einen Algorithmus davon ausgehen können, dass zukünftige Primärschlüssel wiederholt werden können, der Primärschlüssel jedoch eindeutig den Inhalt der Zeile identifiziert, wird nur der zukünftige Primärschlüssel als Hash-Wert bezeichnet und auf Wiederholung geprüft .

0
ron

Ich denke, es sollte nicht mehr erforderlich sein, als nach allen Spalten zu gruppieren, außer nach der id und der Auswahl einer Zeile aus jeder Gruppe - der Einfachheit halber nur die erste Zeile, aber das spielt keine Rolle, außer, Sie haben zusätzliche Einschränkungen für die ID.

Oder andersherum, um die Zeilen loszuwerden. Löschen Sie einfach alle Zeilen, und akzeptieren Sie eine einzige aus allen Gruppen.

0

Hier ist eine, auf die ich im wirklichen Leben gestoßen bin.

Angenommen, Sie verfügen über eine Tabelle mit externen Anmeldungen von Drittanbietern für Benutzer. Sie führen zwei Benutzer zusammen und möchten die Schlüsselwerte des Anbieters/Anbieters entlasten.

    ;WITH Logins AS
    (
        SELECT [LoginId],[UserId],[Provider],[ProviderKey]
        FROM [dbo].[UserLogin] 
        WHERE [UserId][email protected] -- is the user we're deleting
              OR [UserId][email protected] -- is the user we're moving data to
    ), Ranked AS 
    (
        SELECT Logins.*
            , [Picker]=ROW_NUMBER() OVER (
                       PARTITION BY [Provider],[ProviderKey]
                       ORDER BY CASE WHEN [UserId][email protected] THEN 1 ELSE 0 END)
        FROM Logins
    )
    MERGE Logins AS T
    USING Ranked AS S
    ON S.[LoginId]=T.[LoginID]
    WHEN MATCHED AND S.[Picker]>1 -- duplicate Provider/ProviderKey
                 AND T.[UserID][email protected] -- safety check 
    THEN DELETE
    WHEN MATCHED AND S.[Picker]=1 -- the only or best one
                 AND T.[UserID][email protected]
    THEN UPDATE SET T.[UserID][email protected]
    OUTPUT $action, DELETED.*, INSERTED.*;
0
IDisposable
delete from yourTable 
where Id not in (
    select min(id) 
    from yourTable
    group by <Unique Columns>
)

wobei ID ist, was auch immer Ihre eindeutige ID in der Tabelle ist. (Könnte customerNumber oder was auch immer sein)

Wenn Sie keine eindeutige ID haben, können Sie eine hinzufügen (jede SQL - Tabelle sollte bereits eine ID als erste Spalte haben, aber

ALTER TABLE yourTable
ADD Id int identity(1,1)

Lösche (oben) und lösche die Spalte.

Besser, als eine ganz neue Tabelle zu erstellen, oder eines der anderen kryptischen Dinge, die ich gesehen habe. Beachten Sie, so ziemlich das gleiche wie in einem Kommentar hier, aber das ist, was ich seit Jahren getan habe.

0
Traderhut Games

Für Deduplizieren/Deduplizieren/Duplizieren entfernen/Wiederholte Zeilen entfernen/数据库 除 重/数据库 去除 重复 记录 , gibt es mehrere Möglichkeiten.

  1. Wenn doppelte Zeilen genau gleich sind, verwenden Sie group by 

    erstellen Sie die Tabelle TABLE_NAME_DEDUP
    als select column1, column2, ... (alle Spaltennamen) aus der TABLE_NAME-Gruppe nach column1, column2, - alle Spaltennamen

Dann ist TABLE_NAME_DEDUP die deduplizierte Tabelle.

Zum Beispiel,

create table test (t1 varchar(5), t2 varchar(5));
insert into test  values ('12345', 'ssdlh');
insert into test  values ('12345', 'ssdlh');
create table test_dedup as
select * from test 
group by t1, t2;
-----optional
--remove original table and rename dedup table to previous table
--this is not recommend in dev or qa. DROP table test; Alter table test_dedup rename to test;
  1. Sie haben eine Zeilen-ID, die Zeilen-ID hat eine Duplizierung, aber andere Spalten sind unterschiedlich Datensätze sind teilweise identisch. Dies kann in einem Transaktionssystem beim Aktualisieren einer Zeile passieren, und die Zeilen, deren Aktualisierung fehlgeschlagen ist, weisen Nullwerte auf . Sie möchten sie entfernen die Vervielfältigung

    erstellen Sie die Tabelle test_dedup asselect column1, column2, ... (alle Spaltennamen) von ( select * , row_number () over (Partition nach Rowid-Reihenfolge nach Spalte1, Spalte2, ..) . (alle Spaltennamen außer rowid)) als cn aus test ) wobei cn = 1 ist

Hierbei wird die Funktion verwendet, dass bei Verwendung von order by der Nullwert hinter dem Nicht-Nullwert angeordnet wird.

create table test (rowid_ varchar(5), t1 varchar(5), t2 varchar(5));
insert into test  values ('12345', 'ssdlh', null);
insert into test  values ('12345', 'ssdlh', 'lhbzj');
create table test_dedup as
select rowid_, t1, t2 from
(select *
  , row_number() over (partition by rowid_ order by t1, t2) as cn
  from  test)
 where cn =1
 ;

-----optional
--remove original table and rename dedup table to previous table
--this is not recommend in dev or qa. DROP table test; Alter table test_dedup rename to test;
0
Decula

Bin heute auf das Problem gestoßen, keine der vorhandenen Antworten hat mir geholfen. Angenommen, Sie möchten Ihre Tabelle mit dem Namen your_table Deduplizieren.

Schritt 1: Erstellen Sie eine neue Tabelle mit dedupierten Werten

Wenn Sie diesen Code von einem anderen Ort auf StackOverflow ausgeliehen haben, ihn aber nicht wiederzufinden scheinen. Es funktioniert gut gegen PostgreSQL. Es wird eine Tabelle your_table_deduped Erstellt, in der (col1, col2) Eindeutig ist.

CREATE TABLE your_table_deduped AS
SELECT * FROM your_table WHERE ctid NOT IN
(SELECT ctid FROM
  (SELECT ctid, ROW_NUMBER() OVER
    (PARTITION BY col1, col2 ORDER BY ctid) AS rnum
  FROM your_table) t
WHERE t.rnum > 1);

Schritt 2: Ersetzen Sie Ihre erste Tabelle durch die dedupierte Kopie

In diesem Schritt werden nur die Werte gelöscht, da wir damit die Indizes, Einschränkungen usw. in Ihrer Tabelle behalten können.

DELETE FROM your_table;
INSERT INTO your_table
SELECT * FROM your_table_deduped;

Schritt 3: Deduplizierte Kopie löschen

DROP TABLE site_daily_kpis_dedup;

Und voila, du hast deinen Tisch dedupliziert!

0

Diese Methoden funktionieren zwar, aber ohne eine explizite ID als PK. Dann kann bestimmt werden, welche Zeilen gelöscht werden müssen. Das Abspringen in eine temporäre Tabelle aus dem Original löschen und erneut einfügen ohne die Dupes scheint am einfachsten zu sein.

0