Какой лучший способ дедупликации таблицы? - PullRequest
29 голосов
/ 09 февраля 2010

Я видел несколько решений для этого, но мне интересно, какой лучший и самый эффективный способ состоит в том, чтобы де-дупле стол. Вы можете использовать код (SQL и т. Д.), Чтобы проиллюстрировать свою точку зрения, но я просто ищу базовые алгоритмы. Я предполагал, что уже будет вопрос об этом на SO, но я не смог найти его, поэтому, если он уже существует, просто дайте мне знать.

(Просто чтобы уточнить - я имею в виду избавление от дубликатов в таблице, в которой имеется пошаговое автоматическое PK и есть строки, которые являются дубликатами во всем, кроме поля PK.)

Ответы [ 15 ]

12 голосов
/ 09 февраля 2010

SELECT DISTINCT <insert all columns but the PK here> FROM foo. Создайте временную таблицу, используя этот запрос (синтаксис зависит от РСУБД, но обычно доступен шаблон SELECT … INTO или CREATE TABLE AS), затем сдуйте старую таблицу и перекачайте в нее данные из временной таблицы.

8 голосов
/ 24 августа 2014

Использование аналитической функции row_number:

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                                                                 
7 голосов
/ 09 февраля 2010

Дедупинг редко бывает простым. Это потому, что записи, которые должны быть дедуплированы, часто имеют немного разные значения - это некоторые из полей. Поэтому выбрать, какую запись сохранить, может быть проблематично. Кроме того, дупсы - это записи о людях, и трудно определить, являются ли два Джона Смита двумя людьми или одним человеком, который дублируется. Поэтому потратьте большую часть (50% или более от всего проекта) своего времени на определение того, что представляет собой дубликат, и как обрабатывать различия и дочерние записи.

Откуда вы знаете, какое значение является правильным? Дальнейшая дедупликация требует, чтобы вы обрабатывали все дочерние записи, не являющиеся сиротами. Что происходит, когда вы обнаруживаете, что, изменяя идентификатор дочерней записи, вы внезапно нарушаете один из уникальных индексов или ограничений - это произойдет в конце концов, и ваш процесс должен это обработать. Если вы по глупости решили применить все свои ограничения только тщательно, вы можете даже не знать, что ограничения нарушены. Когда у вас есть 10000 записей для дедупликации, вы не собираетесь просматривать приложение для дедупликации по одной за раз. Если ограничение отсутствует в базе данных, удачи в сохранении целостности данных при дедупликации.

Еще одним осложнением является то, что дупли не всегда совпадают точно по имени или адресу. Например, торговый представитель по имени Джоан Мартин может быть дубликатом имени торгового представителя Джоан Мартин-Джонс, особенно если у них одинаковый адрес и адрес электронной почты. ИЛИ вы могли бы иметь имя Джона или Джонни. Или тот же адрес, кроме одной сокращенной записи ST. и одна прописана улица. На сервере SQL вы можете использовать SSIS и нечеткую группировку для определения близких совпадений. Это часто самые распространенные ошибки, так как тот факт, что они не были точными совпадениями, является причиной того, что они были поставлены как первые.

Для некоторых типов дедупликации вам может потребоваться пользовательский интерфейс, чтобы лицо, выполняющее дедупликацию, могло выбрать, какое из двух значений использовать для определенного поля. Это особенно верно, если человек, которого дедуплицируют, играет две или более роли. Может случиться так, что данные для определенной роли обычно лучше, чем данные для другой роли. Или может быть так, что только пользователи наверняка будут знать, какое значение является правильным, или им может понадобиться связаться с людьми, чтобы выяснить, действительно ли они дураки, или просто два человека с одинаковыми именами.

6 голосов
/ 26 апреля 2016

Добавление актуального кода здесь для дальнейшего использования

Итак, есть 3 шага и, следовательно, 3 оператора SQL:

Шаг 1: Переместить недопустимые копии (уникальные кортежи) во временную таблицу

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

Шаг 2: удалить старую таблицу (или переименовать ее) Нам больше не нужна таблица со всеми повторяющимися записями, поэтому оставьте ее!

DROP TABLE old_table;

Шаг 3: переименуйте new_table в имя old_table

RENAME TABLE new_table TO old_table;

И, конечно же, не забудьте исправить свой глючный код, чтобы прекратить вставку дубликатов!

3 голосов
/ 03 октября 2013

Вот метод, который я использую, если вы можете получить свои критерии дублирования в выражении group by, и в вашей таблице есть столбец идентификатора идентификатора для уникальности:

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

В этом примере date_time является критерием группировки, если у вас есть более одного столбца, обязательно присоединитесь ко всем из них.

2 голосов
/ 02 апреля 2014

Я беру один из DShook и даю пример дедупликации, где вы будете хранить только записи с самой высокой датой.

В этом примере, скажем, у меня есть 3 записи с одинаковым app_id, и я хочу сохранить только одну с самой высокой датой:

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
1 голос
/ 20 декабря 2012

Для тех из вас, кто предпочитает быстрый и грязный подход, просто перечислите все столбцы, которые вместе определяют уникальную запись, и создайте уникальный индекс с этими столбцами, например:

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

Вы можете удалить уникальный индекс после слов.

0 голосов
/ 23 апреля 2019

Сегодня столкнулся с проблемой, ни один из существующих ответов не помог мне. Предположим, вы хотите дедуплицировать вашу таблицу с именем your_table.

Шаг 1: Создать новую таблицу с дедуплицированными значениями

Если этот код был заимствован где-то еще в StackOverflow, но, похоже, не может найти его снова. Он отлично работает против PostgreSQL. Создает таблицу your_table_deduped, где (col1, col2) уникальны.

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);

Шаг 2: замените первую таблицу дедуплицированной копией

Мы удаляем только значения на этом шаге, поскольку он позволяет нам сохранить индексы, ограничения и т. Д. В вашей таблице.

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

Шаг 3: Удалить дедуплицированную копию

DROP TABLE site_daily_kpis_dedup;

И вуаля, вы дедуплицировали свой стол!

0 голосов
/ 03 ноября 2018

Для дедупликации / дедупликации / удаления дублирования / удаления повторяющихся строк / 数据库 除 重 / 数据库 去除 重复 记录 , существует несколько способов.

  1. Если дублирующиеся строки в точности совпадают, используйте группирование по

    создать таблицу TABLE_NAME_DEDUP
    как выбрать column1, column2, ... (все имена столбцов) из группы TABLE_NAME по столбцу1, столбцу2, - все имена столбцов

Тогда TABLE_NAME_DEDUP является дедуплицированной таблицей.

Например,

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. У вас есть идентификатор строки, идентификатор строки дублируется, но другие столбцы отличаются Частичные записи аналогичны, это может происходить в транзакционной системе при обновлении строки, и строки, которые не удалось обновить, будут иметь нулевые значения. Вы хотите удалить дубликаты

    создать таблицу test_dedup как выберите column1, column2, ... (все имена столбцов) от ( Выбрать * , row_number () over (разделение по порядку rowid по column1, column2, ... (все имена столбцов, кроме rowid)) как cn из теста ) где cn = 1

Это использует функцию, которая при использовании порядка по, нулевое значение будет упорядочено после ненулевого значения.

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 голосов
/ 11 января 2018

Эти методы будут работать, но без явного идентификатора в качестве PK, тогда определение проблемных строк может быть проблемой. Отскок в временную таблицу, удаление из оригинала и повторную вставку без дубликатов, кажется самым простым.

...