2010-02-24 1 views
7

Сценарий: у меня немного дублированных контактов в таблице. Дубликаты идентифицированы, я могу просто удалить их, но проблема в том, что я не хочу терять данные, которые может иметь дубликат, а оригинал - нет. Какие-нибудь советы?MySQL - Дублирование устранения и сохранение ценных данных?

Образец данных:

ID Name Email School Dupe_Flag Key 
1 AAA [email protected]   X   1 
2 AAB  JKL    1 
3 BBB [email protected] MNO X   2 
4 BBC       2 

Желаемый результат:

ID Name Email School Dupe_Flag Key 
1 AAA [email protected]   X   1 
2 AAB [email protected] JKL    1 
3 BBB [email protected] MNO X   2 
4 BBC [email protected] MNO    2 

Как связаны 2 записи? : Оба они имеют одинаковое значение ключа только с одним столбцом, имеющим Dupe_Flag SET, который является дублирующимся столбцом.

В приведенном выше случае ID 1 собирается быть удален, но электронная почта информация от ID 1 должен быть применен к ID 2.

Что такое данные? : У меня есть несколько сотен строк и несколько 100 дубликатов. Оператор UPDATE для каждой строки является громоздким и невозможен.

Бизнес-правила для определения того, какие данные имеют приоритет:

Если столбец из исходной/хороший запись (Dupe_Flag не установлен) не имеет никаких данных, и если соответствующая Dupe запись (имеет один и тот же ключ значение) столбец имеет данные, тогда исходный столбец записи должен быть обновлен.

Любая помощь/скрипт действительно оценена! Спасибо, ребята :)

+2

, как мы можем видеть, какие строки вы считаете дублировать? как узнать, какие столбцы в обманах вы считаете более ценными, чем соответствующий столбец в строке, которую вы хотите сохранить? - без спецификации вы не можете автоматизировать операцию. –

+0

Сначала вам нужно определить свои собственные бизнес-правила для определения того, какие данные имеют приоритет в случае конфликта. – Dolph

+0

Dupe_Flag указывает, что это дубликат. Какие данные имеют приоритет? - Простой на самом деле. Если какой-либо из столбцов для оригинальной (хорошей) записи NULL, и если одни и те же столбцы не являются NULL в записи Duplicate, мы просто обновляем эти столбцы. Обновлен мой вопрос для ясности. Спасибо! – ThinkCode

ответ

0

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

Мне нравится использовать этот запрос для отслеживания простофили:

select * from table group by `Email` having count(Email) > 1 
+0

Это всего лишь образец данных. У меня теперь есть ключи на месте, просто некоторые контакты имеют разные первые средние имена, и, следовательно, мы не можем обнулить обман по программным средствам. Только ручная проверка может идентифицировать, поэтому проблема :( Я установил электронную почту на уникальный битв, данные образца были только для иллюстративных целей. Спасибо .. – ThinkCode

+0

Только ручная проверка сообщит вам (или позволит вам угадать), что данные вернее. С разными средними именами, что правильно? Программа не знает. И иногда, по крайней мере, с вашим примером, даже если это похоже на дубликат, это действительно отдельная запись (два человека с одинаковыми имя). – thursdaysgeek

+0

Поверьте мне, ребята, у нас есть повторные проверки на месте. Все, что я хочу знать, это самый простой/эффективный способ спасти данные, связанные с записью обмана. – ThinkCode

-1

Строки являются уникальными, так что нет никаких проблем. Повторите проверку данных примера.

0

Хотя это использует кучу вложенных SELECTS и на самом деле не является полным решением, оно должно либо зажечь что-то другое, либо, возможно, нажать в правильном направлении.

select * from 
    (select r1.ID,r1.Name,coalesce(r1.Email,r2.Email) as Email, 
    coalesce(r1.School,r2.School) as School,r1.Dupe_Flag,r1.Key from 
    (select * from test1 where Dupe_Flag IS NULL) as r1 left outer join 
    (select * from test1 where Dupe_Flag IS NOT NULL) as r2 on r1.KEY=r2.Key) 
as results 

Урожайность:

ID Name Email School Dupe_Flag Key 
2 AAB [email protected] JKL  NULL  1 
4 BBC [email protected] MNO  NULL  2 

Основываясь на вашем примере данных.

+0

Спасибо, я действительно пытался устранить необходимость запросов на каждый столбец, так как реальные данные получили так много столбцов. Идеальное решение до сих пор было бы скриптом PYTHON, который хранит все столбцы в массиве и проверяет любые ценные данные и обновляет исходный столбец. – ThinkCode

+0

Решение, приведенное ниже от Benoit Vidis, дает именно то, что вы ищете. – furrymitn

2

Предполагая, что пустые значения равны нулю, то, как это должно выводить нужные данные:

SELECT 
    a.ID, 
    IF(a.DupeFlag IS NULL, IF(a.Name IS NULL, b.Name, a.Name), a.Name) AS Name, 
    IF(a.DupeFlag IS NULL, IF(a.Email IS NULL, b.Email, a.Email), a.Email) AS Email, 
    IF(a.DupeFlag IS NULL, IF(a.School IS NULL, b.School, a.School), a.School) as School, 
    a.DupeFlag, 
    a.key 
FROM 
    table a, 
    table b 
WHERE 
    a.Key = b.Key AND 
    a.ID != b.ID 
GROUP BY 
    a.ID 

Обратите внимание, что включение этого в операторе UPDATE является довольно прямо вперед

+0

Большое спасибо! Мой вопрос остается, потому что это только образцы данных, в действительности у меня есть сотни столбцов, поэтому инструкции UPDATE для каждого из них не будут делать трюк :( Еще раз спасибо! – ThinkCode