views:

111

answers:

4

Scenario : I have few duplicate contacts in a table. The duplicates are identified, I can just delete them but the problem is I don't want to lose the data the duplicate might have and the original don't. Any tips?

Sample data :

ID Name Email School Dupe_Flag Key
1  AAA  a@a          X         1 
2  AAB        JKL              1
3  BBB  b@b   MNO    X         2
4  BBC                         2

Desired output :

ID Name Email School Dupe_Flag Key
1  AAA  a@a          X         1 
2  AAB  a@a   JKL              1
3  BBB  b@b   MNO    X         2
4  BBC  b@b   MNO              2

How are 2 records related? : They both have the same Key Value with only one column having the Dupe_Flag SET which is the duplicate column.

In the above case ID 1 is going to be deleted but email info from ID 1 should be applied to ID 2.

What is the Data? : I have few hundred rows and few 100 duplicates. UPDATE statement for each row is cumbersome and is not feasible.

Business rules for determining what data takes priority :

If a column from the original/good record (Dupe_Flag is NOT set) has no data and if the corresponding Dupe record (has the same Key value) column has data then that original record column should be updated.

Any help/script is really appreciated! Thanks guys :)

A: 

I don't know the specifics of this problem but it is probably better to avoid this problem by setting the columns to "unique" so if a query tries to create a duplicate it will fail. I think the elegant solution to this problem is to avoid it at the point of data entry.

I like using this query for tracking down dupes:

select * from table group by `Email` having count(Email) > 1
Rook
It is just sample data. I now have keys in place, it is just that some contacts have different first middle names and hence, we cannot zero in on the dupe by program means. Only manual review can identify, hence the problem :( I set Email to unique btw, the sample data was just for illustration purposes.Thank you..
ThinkCode
Only manual review will tell you (or allow you to guess) which data is more correct. With different middle names, which is correct? A program wouldn't know. And occasionally, at least with your example, even though it looks like a duplicate, it really is a separate record (two people with the same name).
thursdaysgeek
Trust me guys, we have duplicate detection checks in place. All I want to know is the easiest/efficient way to salvage the data associated to the dupe record.
ThinkCode
A: 

The rows are unique, so there's no problem. Please recheck your example data.

pete
A: 

While this uses a bunch of nested SELECTS, and isn't really a full solution, it should either spark something else, or possibly push in the right direction.

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

Yields:

ID  Name  Email  School  Dupe_Flag  Key
2   AAB   a@a    JKL     NULL       1
4   BBC   b@b    MNO     NULL       2

Based on your example data.

furrymitn
Thank you! I was actually trying to eliminate the need for queries on every column since real data got so many columns.An idea solution so far would be a PYTHON script which stores all columns in an array and check for any valuable data and update the original column.
ThinkCode
The solution below from Benoit Vidis yields exactly what you are looking for.
furrymitn
+2  A: 

Assuming empty values are null, something like this should output the desired data:

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

Note that turning this in an UPDATE statement is pretty straight-forward

Benoit Vidis
Thanks a lot!My question remains cos' this is just sample data, in reality I have hundreds of columns, so UPDATE statements on each one of them will not do the trick :(Thanks again!
ThinkCode