Comparar dos conjuntos de datos

Una carga de productos debería coincidir con la tabla actual, pero necesitamos saber qué filas faltan y cuáles contienen valores diferentes. Comparar solo el número de registros puede ocultar cambios importantes.

Qué necesitamos distinguir

Un conjunto es el grupo de filas producido por una consulta. La proyección es la lista de columnas seleccionadas; dos filas se comparan según todos los valores proyectados.

Separaremos las filas que existen únicamente en la tabla actual de las que existen únicamente en la carga. La comparación incluirá identificador, nombre, precio y estado; cualquier diferencia en esas columnas hará que la fila aparezca en el resultado.

Consulta

/*
    Antes de ejecutar:
        Revisa la base activa, los nombres de objetos, los parámetros y los permisos.
        Adapta el ejemplo a tu modelo y pruébalo primero en un ambiente controlado.
*/

SET NOCOUNT ON;
GO
-- Comparación con EXCEPT
WITH DatosActuales AS
(
    SELECT
        p.IdProducto,
        p.Nombre,
        p.Precio,
        p.Activo
    FROM dbo.Producto AS p
),
DatosCarga AS
(
    SELECT
        pi.IdProducto,
        pi.Nombre,
        pi.Precio,
        pi.Activo
    FROM dbo.ProductoImportado AS pi
)
SELECT
    N'Solo en actual o con valores anteriores' AS Diferencia,
    a.IdProducto,
    a.Nombre,
    a.Precio,
    a.Activo
FROM
(
    SELECT IdProducto, Nombre, Precio, Activo
    FROM DatosActuales
    EXCEPT
    SELECT IdProducto, Nombre, Precio, Activo
    FROM DatosCarga
) AS a
UNION ALL
SELECT
    N'Solo en carga o con valores nuevos' AS Diferencia,
    c.IdProducto,
    c.Nombre,
    c.Precio,
    c.Activo
FROM
(
    SELECT IdProducto, Nombre, Precio, Activo
    FROM DatosCarga
    EXCEPT
    SELECT IdProducto, Nombre, Precio, Activo
    FROM DatosActuales
) AS c
ORDER BY
    IdProducto,
    Diferencia;
GO

-- Variante con FULL OUTER JOIN
SELECT
    COALESCE(p.IdProducto, pi.IdProducto) AS IdProducto,
    p.Precio AS PrecioActual,
    pi.Precio AS PrecioCarga
FROM dbo.Producto AS p
FULL OUTER JOIN dbo.ProductoImportado AS pi
    ON pi.IdProducto = p.IdProducto
WHERE p.IdProducto IS NULL
   OR pi.IdProducto IS NULL
   OR EXISTS
      (SELECT p.Nombre, p.Precio, p.Activo
       EXCEPT
       SELECT pi.Nombre, pi.Precio, pi.Activo);
GO

Parámetros o permisos

Las dos proyecciones deben tener el mismo número de columnas, en el mismo orden y con tipos compatibles. Elige únicamente columnas relevantes para la comparación. Fechas de carga, marcas de actualización o valores calculados pueden producir diferencias esperadas en todas las filas. La consulta requiere lectura sobre ambos conjuntos. Si se comparan bases diferentes en la misma instancia, utiliza nombres de tres partes y confirma los permisos y la intercalación de las columnas de texto.

Cómo leer el resultado

Una fila presente solo en uno de los conjuntos aparece una vez. Si el mismo IdProducto existe en ambos pero cambió el precio, aparecerán dos filas: una con los valores actuales y otra con los valores de la carga. EXCEPT devuelve filas distintas; no conserva repeticiones dentro de un conjunto. También considera equivalentes dos valores NULL que ocupan la misma posición durante esta comparación. Cuando necesitamos ver valores anteriores y nuevos en una sola fila, una variante con FULL OUTER JOIN resulta más apropiada: SELECT COALESCE(p.IdProducto, pi.IdProducto) AS IdProducto, p.Precio AS PrecioActual, pi.Precio AS PrecioCarga FROM dbo.Producto AS p FULL OUTER JOIN dbo.ProductoImportado AS pi ON pi.IdProducto = p.IdProducto WHERE p.IdProducto IS NULL OR pi.IdProducto IS NULL OR EXISTS (SELECT p.Nombre, p.Precio, p.Activo EXCEPT SELECT pi.Nombre, pi.Precio, pi.Activo);

Qué conclusión sí permite obtener

Permite detectar diferencias entre las columnas seleccionadas y reconocer en qué conjunto aparece cada versión.

Qué conclusión todavía no permite obtener

La multiplicidad es el número de veces que aparece una misma fila. EXCEPT elimina repeticiones y no permite compararlas directamente.

No determina cuál conjunto es correcto ni explica la causa del cambio. Tampoco compara multiplicidad cuando las proyecciones contienen filas duplicadas.

Siguiente comprobación razonable

Clasifica las diferencias como altas, bajas o modificaciones según la llave de negocio. Después revisa fechas, origen y reglas de transformación antes de generar cualquier sincronización.

Índice del recorrido

Desarrollo y exploración

22 artículos de Desarrollo y exploración
  1. 01Buscar una tabla o vista por nombre
  2. 02Buscar una columna en toda la base
  3. 03Buscar texto dentro de procedimientos, vistas y funciones
  4. 04Consultar dependencias de un objeto
  5. 05Listar relaciones y llaves foráneas
  6. 06Consultar llaves primarias, restricciones únicas e índices
  7. 07Listar columnas con tipo, longitud, nulabilidad y valor predeterminado
  8. 08Encontrar triggers y sus tablas asociadas
  9. 09Encontrar objetos modificados recientemente
  10. 10Obtener conteos aproximados de todas las tablas
  11. 11Medir el espacio utilizado por cada tabla
  12. 12Revisar columnas IDENTITY y su valor actual
  13. 13Detectar registros duplicados por una clave de negocio
  14. 14Detectar registros huérfanos
  15. 15Comparar dos conjuntos de datos
  16. 16Validar conversiones antes de modificar una columna
  17. 17Ejecutar un UPDATE con validación y reversión controlada
  18. 18Ejecutar un DELETE con respaldo lógico y reversión controlada
  19. 19Comparar la estructura de dos bases de datos
  20. 20Describir el resultado de una consulta o procedimiento
  21. 21Encontrar tablas sin llave primaria
  22. 22Buscar un valor en columnas seleccionadas