HOWTO · MySQL

Diferencia entre dos tablas en MySQL

En la publicación de hoy, aprenderemos a encontrar la diferencia entre dos tablas en MySQL.

En esta página

Al validar una transferencia de datos de un sistema heredado a uno nuevo, quizá necesites encontrar valores seleccionados de filas que aparecen en una tabla, pero no en la otra. Este método compara valores de filas, no esquemas de tablas ni todos los tipos de cambios. Elige las columnas relevantes para verificar la transferencia; la consulta solo puede detectar diferencias en esos valores seleccionados.

Buscar filas diferentes entre dos tablas de MySQL

El método combina las filas seleccionadas de ambas tablas, agrupa las tuplas seleccionadas idénticas y conserva los grupos que aparecen una sola vez. UNION ALL agrega filas y conserva las apariciones duplicadas; no es un join. COUNT(*) cuenta las filas de cada grupo, pero por sí solo no comprueba si los valores son similares. Si una tupla aparece una vez en cada tabla, su grupo tiene un recuento de dos. Una tupla presente en una sola tabla tiene un recuento de uno, siempre que se cumplan los supuestos indicados más abajo.

Preparar filas comparables de ambas tablas

Ambas instrucciones SELECT deben devolver el mismo número de columnas compatibles y en el mismo orden. Siempre que sea posible, usa tipos de datos coincidentes y selecciona la clave junto con todos los valores que quieras comparar. Por ejemplo, la consulta puede escribirse así: SELECT employee_id, department, email FROM (SELECT employee_id, department, email FROM employee_old_table UNION ALL SELECT employee_id, department, email FROM employee_new_table) AS combined GROUP BY employee_id, department, email HAVING COUNT(*) = 1 ORDER BY employee_id;. El alias de la tabla derivada asigna un nombre al resultado combinado. Agrupa por todas las columnas seleccionadas para que solo se cuenten juntas las filas cuyos valores coincidan en toda la tupla seleccionada.

Buscar filas que aparecen en una sola tabla

HAVING COUNT(*) = 1 filtra las filas agrupadas después de la agrupación. El resultado contiene cada tupla seleccionada que aparece exactamente una vez en la entrada combinada. ORDER BY employee_id facilita la inspección del resultado, pero no afecta a qué tuplas coinciden. Conserva UNION ALL: UNION sin ALL elimina las filas duplicadas antes de agrupar y puede alterar los recuentos, ocultando discrepancias relacionadas con duplicados.

La consulta SQL está pensada para un servidor MySQL y no se ejecuta con el entorno disponible para los ejemplos del artículo. Ese entorno sí ejecuta esta ilustración en Python con las tuplas de empleados proporcionadas; su salida aparece abajo. La ilustración muestra la idea de agrupar, pero no sustituye la ejecución de la consulta SQL en tus tablas. Los valores de texto visibles en el ejemplo, incluidas las denominaciones de departamentos, permanecen en inglés porque el bloque de código se conserva idéntico al original.

Ejecuta esta ilustración:

from collections import Counter

old_rows = [(12, "Sales", "maya@example.com"), (14, "TeleCom", "john_doe@example.com"), (15, "TeleCom", "jane@example.com")]
new_rows = [(12, "Sales", "maya@example.com"), (14, "TeleCom", "john_doe@example.com"), (15, "TeleCommunication", "johndoe@example.com")]
counts = Counter(old_rows + new_rows)
unmatched = sorted(row for row, count in counts.items() if count == 1)
for row in unmatched:
    print(*row, sep=" | ")
15 | TeleCom | jane@example.com
15 | TeleCommunication | johndoe@example.com

Entender el ejemplo de empleados

Supongamos que employee_old_table y employee_new_table contienen, cada una, como máximo una fila por employee_id. Las columnas seleccionadas son employee_id, department y email. Los empleados 12 y 14 tienen los mismos valores seleccionados en ambas tablas. En el caso del empleado 15, cambiaron el departamento y el correo electrónico, por lo que cada versión constituye una tupla sin coincidencia. Por tanto, el resultado agrupado contiene las dos tuplas del empleado 15. Como la consulta agrupa por cada valor seleccionado, no empareja las versiones antigua y nueva en un único registro de cambios.

Comprobar los supuestos y las limitaciones

La interpretación de un recuento de uno depende de que cada tupla seleccionada aparezca como máximo una vez en cada tabla. Las filas duplicadas pueden hacer que el recuento del grupo de una tupla sea dos o más, aunque esa misma tupla no aparezca una vez en cada tabla; los recuentos por sí solos no indican qué tabla aportó cada fila. En el ejemplo de empleados, el supuesto de una fila por clave ayuda a interpretar los resultados, pero los duplicados o las claves repetidas requieren un diseño de comparación más específico.

El resultado identifica tuplas seleccionadas sin coincidencia, pero no indica de qué tabla procede cada una. Tampoco puede detectar cambios en columnas omitidas de la lista SELECT, comparar definiciones de columnas ni explicar por qué cambió un valor. Si necesitas atribuir una tupla a su tabla de origen, incluye una etiqueta de origen en cada SELECT y usa una consulta diseñada para conservarla; esto cambia el comportamiento de la agrupación y queda fuera de este método sencillo basado en un recuento de uno. Antes de considerar el resultado una prueba de que dos tablas completas son idénticas, confirma que las columnas elegidas y la política sobre duplicados se ajustan a la verificación de la transferencia de datos.