2010-02-24 14 views
7

Escenario: Tengo pocos contactos duplicados en una tabla. Los duplicados están identificados, puedo eliminarlos pero el problema es que no quiero perder los datos que el duplicado podría tener y los originales no. ¿Algun consejo? datosMySQL - Eliminación de duplicados y preservación de datos valiosos?

muestra:

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 

salida deseada:

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 

cómo se relacionan 2 registros? : Ambos tienen el mismo valor de clave con solo una columna que tiene el Dupe_Flag SET que es la columna duplicada.

En el caso de la identificación por encima de 1 va a ser eliminado, pero Información de correo electrónico de identificación 1 debe ser aplicado a Identificación 2.

¿Qué son los datos? : Tengo pocas cientos filas y pocos 100 duplicados. La instrucción UPDATE para cada fila es engorrosa y no es factible.

Las reglas de negocio para determinar qué datos tiene prioridad:

Si una columna del registro original/bueno (Dupe_Flag NO está establecido) no tiene datos y si el registro Dupe correspondiente (tiene el mismo valor de clave) la columna tiene datos entonces esa columna de registro original debe actualizarse.

¡Cualquier ayuda/script es realmente apreciada! Gracias chicos :)

+2

¿Cómo podemos ver las filas que se tiene en cuenta ¿duplicar? ¿Cómo podemos saber qué columnas de los engaños considera más valiosas que la columna correspondiente en la fila que desea conservar? - sin una especificación, no puede automatizar la operación. –

+0

Primero necesita definir sus propias reglas comerciales para determinar qué datos tienen prioridad en caso de conflicto. – Dolph

+0

Dupe_Flag indica que es un duplicado. ¿Qué datos tienen prioridad? - Simple realmente. Si alguna de las columnas para el registro original (bueno) es NULA y si las mismas columnas NO SON NULAS en el registro Duplicado, entonces simplemente actualizamos esas columnas. Actualicé mi pregunta para mayor claridad. ¡Gracias! – ThinkCode

Respuesta

0

No conozco los detalles de este problema, pero probablemente sea mejor evitar este problema estableciendo las columnas como "únicas", por lo que si una consulta intenta crear un duplicado, fallará. Creo que la solución elegante a este problema es evitarlo en el momento de la entrada de datos.

me gusta usar esta consulta para la localización de duplicados:

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

Son solo datos de muestra. Ahora tengo las llaves en su lugar, es solo que algunos contactos tienen diferentes primeros nombres intermedios y, por lo tanto, no podemos concentrarnos en los engañados por los medios del programa. Solo la revisión manual puede identificar, de ahí el problema :( Establecí el correo electrónico como único por cierto, los datos de muestra fueron solo para fines ilustrativos Gracias .. – ThinkCode

+0

Solo la revisión manual le dirá (o le permitirá adivinar) cuál los datos son más correctos. Con diferentes nombres intermedios, ¿cuál es el correcto? Un programa no lo sabría. Y ocasionalmente, al menos con su ejemplo, aunque parezca un duplicado, en realidad es un registro separado (dos personas con el mismo nombre). – thursdaysgeek

+0

Créanme chicos, tenemos comprobaciones de detección duplicadas en su lugar. Todo lo que quiero saber es la forma más fácil/eficiente de salvar los datos asociados al registro de engaño. – ThinkCode

-1

Las filas son únicos, así que no hay problema. Por favor vuelva a verificar sus datos de ejemplo.

0

Si bien esto utiliza un grupo de SELECT anidados, y no es realmente una solución completa, debería provocar otra cosa, o posiblemente empujar en la dirección correcta.

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 

Rendimiento:

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

Sobre la base de los datos de ejemplo.

+0

¡Gracias! En realidad, estaba tratando de eliminar la necesidad de consultas en cada columna desde que los datos reales obtuvieron tantas columnas. Una solución de idea hasta ahora sería una secuencia de comandos PYTHON que almacena todas las columnas en una matriz y comprueba si hay datos valiosos y actualiza la columna original. – ThinkCode

+0

La siguiente solución de Benoit Vidis produce exactamente lo que está buscando. – furrymitn

2

Suponiendo que los valores vacíos son nulos, algo como esto debería devolver los datos deseados:

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 

Tenga en cuenta que convertir esto en una sentencia UPDATE es bastante recta hacia adelante

+0

¡Muchas gracias! Mi pregunta sigue siendo porque 'esto es solo datos de muestra, en realidad tengo cientos de columnas, por lo que las afirmaciones de ACTUALIZACIÓN en cada una de ellas no harán el truco :( ¡Gracias de nuevo! – ThinkCode

Cuestiones relacionadas