MySQL дубликаты - как указать, когда две записи на самом деле не дублируют? - PullRequest
1 голос
/ 18 сентября 2010

У меня есть интересная проблема, и моя логика не соответствует задаче.

У нас есть таблица, в которой иногда создаются дублированные записи (по причинам процесса, и это неизбежно).Возьмем следующий пример:

id  FirstName  LastName  PhoneNumber   email
--  ---------  --------  ------------  --------------
 1  John       Doe       123-555-1234  jdoe@gmail.com
 2  Jane       Smith     123-555-1111  jsmith@foo.com
 3  John       Doe       123-555-4321  jdoe@yahoo.com
 4  Bob        Jones     123-555-5555  bob@bar.com
 5  John       Doe       123-555-0000  jdoe@hotmail.com
 6  Mike       Roberts   123-555-9999  roberts@baz.com
 7  John       Doe       123-555-1717  wally@domain.com

Мы находим дубликаты следующим образом:

SELECT c1.* 
FROM `clients` c1
INNER JOIN (
    SELECT `FirstName`, `LastName`, COUNT(*)
    FROM `clients`
    GROUP BY `FirstName`, `LastName`
    HAVING COUNT(*) > 1
) AS c2
ON c1.`FirstName` = c2.`FirstName`
AND c1.`LastName` = c2.`LastName`

. Создается следующий список дубликатов:

id  FirstName  LastName  PhoneNumber   email
--  ---------  --------  ------------  --------------
 1  John       Doe       123-555-1234  jdoe@gmail.com
 3  John       Doe       123-555-4321  jdoe@yahoo.com
 5  John       Doe       123-555-0000  jdoe@hotmail.com
 7  John       Doe       123-555-1717  wally@domain.com

Как вы можетесм., основываясь на FirstName и LastName, все записи являются дубликатами.

На этом этапе мы фактически звоним клиенту по телефону, чтобы выяснить возможные дубликаты.

После этого мы узнаем (например), что записи 1 и 3 являются реальными дубликатами, но записи 5 и 7 фактически являются двумя разными людьми.

Таким образом, мы объединяем любые посторонние данные из записей 1 и 3 взапись 1, удалите запись 3 и оставьте записи 5 и 7.

Теперь возникла проблема:

В следующий раз, когда мы повторно запустим ""дубликаты", он будет содержать следующие строки:

id  FirstName  LastName  PhoneNumber   email
--  ---------  --------  ------------  --------------
 1  John       Doe       123-555-4321  jdoe@gmail.com
 5  John       Doe       123-555-0000  jdoe@hotmail.com
 7  John       Doe       123-555-1717  wally@domain.com

Все они выглядят как дубликаты, даже если мы ранее признавали, что это не так.

КакВы бы пошли на выявление того, что эти записи не дублируютlicates?

Моим первым делом было создание таблицы поиска, определяющей, какие записи не являются дубликатами друг друга (например, {1,5}, {1,7}, {5,7}), но я понятия не имею, как создать запрос, который мог бы использовать эти данные.

Далее, если появляется другая дублирующаяся запись, это может быть дубликат 1, 5 или 7,поэтому нам нужно, чтобы они все были показаны в списке дубликатов, чтобы специалист по обслуживанию клиентов мог позвонить этому человеку в новой записи, чтобы выяснить, к какой записи он может быть дубликатом.

Я растянут кпредел пытается понять это.Есть ли какие-нибудь блестящие гении, которые хотели бы покончить с этим?

Ответы [ 2 ]

1 голос
/ 18 сентября 2010

Интересная проблема. Вот моя трещина в этом.

Как насчет того, чтобы подойти к проблеме с несколько иной точки зрения.

Учтите, что система чиста для начала, т. Е. Все записи, которые в настоящее время находятся в системе, имеют либо уникальные комбинации имени + фамилии, либо одинаковые имена + фамилии, которые уже были вручную подтверждены как разные люди.

В момент ввода НОВОГО пользователя в систему у нас есть дополнительная проверка. Может быть реализован как триггер INSERT или просто как другая процедура, вызываемая после успешного выполнения вставки.

  1. Этот триггер / процедура соответствует FIRST + LAST имя комбинации «Вставленная» запись со всеми существующими записей в таблице.
  2. Для всех совпадающих Имен + Фамилий будет создана запись в соответствующей таблице (новая таблица) с NewUserID, ExistingMatchingRecordsUserID

С точки зрения SQL,

TABLE MatchingTable
COLUMNS 1. NewUserID 2. ExistingUserID
Constraint : Logical PK = NewUserID + ExistingMatchingRecordsUserID

INSERT INTO MATCHINGTABLE VALUES ('NewUserId', userId)
SELECT userId FROM User  u where u.firstName = 'John' and u.LastName = 'Doe'

Все записи в MatchingTable нуждаются в разрешении.

Когда, скажем, администратор входит в систему, он видит список всех записей в MatchingTable

Например: новый пользователь Джон Доу - (ID 345) - 3 совпадения потенциалов Джон Доу - ID 123 ID 231 / ID 256

Администратор проверит данные для 345 против данных в 123/231 и 256 и вручную подтвердит, является ли дубликат ЛЮБЫМ / Нет Если дубликат, 345 удаляется из таблицы пользователей (мягкое / жесткое удаление - все, что вам подходит) Если НЕТ, записи для идентификатора 354 просто удаляются из MatchingTable (я бы пошел с полным удалением здесь, так как это похоже на временную таблицу транзакций, но опять же все в порядке).

Кроме того, когда записи для идентификатора 354 удаляются из MatchingTable, все остальные записи в MatchingTable, где ExistingMatchingRecordsUserID = 354 автоматически удаляются, чтобы гарантировать, что ненужная ручная проверка для уже проверенных данных не требуется.

Опять же, это может быть потенциальный триггер DELETE / логика Just, выполняемая дополнительно в DELETE из MatchingTable. Реализация зависит от предпочтения.

0 голосов
/ 18 сентября 2010

За счет добавления одного байта на строку в таблицу, вы можете добавить столбец manually_verified BOOL со значением по умолчанию FALSE.Установите значение TRUE, если вы проверили данные вручную.Затем вы можете просто запросить, где manually_verified = FALSE.

Это просто, эффективно и соответствует тому, что на самом деле происходит в бизнес-процессах: вы вручную проверяете данные.

Если вы хотите перейтишаг вперед, вы можете сохранить, когда строка была проверена и кто ее проверил.Так как это может раздражать хранение в основной таблице, вы, безусловно, можете сохранить его в отдельной таблице и LEFT JOIN в данных проверки.Вы могли бы даже создать представление, чтобы воссоздать внешний вид одной основной таблицы.

Чтобы решить проблему добавления нового дубликата: вы должны проверить неподтвержденные данные по всем данным.задавать.Таким образом, это означает, что ваша основная таблица c1 будет иметь условие manually_verified = FALSE, а ваша INNER JOIN ed таблица c2 - нет.Таким образом, непроверенные данные все равно найдут все потенциальные совпадения:

SELECT * FROM table t1
INNER JOIN table t2 ON t1.name = t2.name AND t1.id <> t2.id
WHERE t1.manually_verified = FALSE

Возможные совпадения для дубликатов будут в объединенной таблице.

...