Compare two sets of data

A product load should match the current table, but we need to know which rows are missing and which contain different values. Comparing only the number of records can hide important changes.

What we need to distinguish

A set is the group of rows produced by a query. The projection is the list of selected columns; rows are compared using every projected value.

We will separate the rows that exist only in the current table from those that exist only in the load. The comparison will include identifier, name, price and status; any differences in those columns will cause the row to appear in the result.

Query

/*
    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

Parameters or permissions

The two projections must have the same number of columns, in the same order, and with compatible types. Choose only relevant columns for comparison. Load dates, update marks, or calculated values ​​can cause expected differences across rows. The query requires reading about both sets. If comparing different bases on the same instance, use three-part names and confirm permissions and collation of text columns.

How to read the result

A row present in only one of the sets appears once. If the same ProductId exists in both but the price changed, two rows will appear: one with the current values ​​and another with the cargo values. EXCEPT returns distinct rows; it does not preserve repetitions within a set. It also considers two NULL values ​​that occupy the same position to be equivalent during this comparison. When we need to see old and new values in a single row, a variant with FULL OUTER JOIN is more appropriate: SELECT COALESCE(p.ProductId, pi.ProductId) AS ProductId, p.Price AS CurrentPrice, pi.Price AS LoadPrice FROM dbo.Product AS p FULL OUTER JOIN dbo.ImportedProduct AS pi ON pi.ProductId = p.ProductId WHERE p.ProductId IS NULL OR pi.ProductId IS NULL OR EXISTS (SELECT p.Name, p.Price, p.Asset EXCEPT SELECT p.Name, pi.Price, pi.Asset);

What this does establish

It allows you to detect differences between the selected columns and recognize in which set each version appears.

What this still does not establish

Multiplicity is the number of times the same row appears. EXCEPT removes repetitions and does not compare them directly.

It does not determine which set is correct or explain the cause of the change. It also does not compare multiplicity when the projections contain duplicate rows.

Next reasonable check

Classify the differences as additions, deletions or modifications according to the business key. Then review dates, origin, and transformation rules before generating any synchronization.

Path index

Development and exploration

22 articles in Development and exploration
  1. 01Search for a table or view by name
  2. 02Search for a column across the database
  3. 03Search for text inside procedures, views, and functions
  4. 04Inspect the dependencies of an object
  5. 05List relationships and foreign keys
  6. 06Inspect primary keys, unique constraints, and indexes
  7. 07List columns with type, length, nullability, and default value
  8. 08Find triggers and their associated tables
  9. 09Find recently modified objects
  10. 10Get approximate row counts for every table
  11. 11Measure the space used by each table
  12. 12Inspect IDENTITY columns and their current value
  13. 13Find duplicate rows by business key
  14. 14Find orphaned rows
  15. 15Compare two data sets
  16. 16Validate conversions before changing a column
  17. 17Run an UPDATE with controlled validation and rollback
  18. 18Run a DELETE with a logical backup and controlled rollback
  19. 19Compare the structure of two databases
  20. 20Describe the result of a query or stored procedure
  21. 21Find tables without a primary key
  22. 22Search selected columns for a value