Published on

November 16, 2011

Gestión de la limpieza de datos en SQL Server

Cuando se trabaja con la limpieza de datos en SQL Server, es común encontrarse con situaciones en las que es necesario comparar filas y realizar operaciones basadas en ciertas condiciones. Un enfoque para evitar el uso de cursores es utilizando el campo IDENTITY() y self-joins. Sin embargo, este método puede volverse problemático cuando los números de IDENTITY() no son secuenciales debido a filas faltantes.

Afortunadamente, hay un truco que puede ayudar a superar este problema. El truco consiste en utilizar una Expresión de Tabla Común (CTE) y la función de ventana ROW_NUMBER() como parte de una instrucción UPDATE. Esta técnica se puede utilizar en SQL Server 2005 o superior.

Echemos un vistazo a un ejemplo para demostrar este truco:


-- Configurar una variable de tabla con algunos datos que tienen duplicados y algunos duplicados inciertos
DECLARE @SomeData TABLE (
    RowID INT UNIQUE,
    EmpID VARCHAR(8),
    PositionTitle VARCHAR(40),
    PositionEffDate DATETIME,
    PositionID VARCHAR(8)
);

-- Insertar datos de muestra en la variable de tabla
INSERT INTO @SomeData VALUES
    (1, '00000012', 'Gerente', '1/1/2000', 'ABC123'),
    (2, '00000012', 'Gerente', '1/1/2000', 'ABC123ZZ'),
    (3, '00000012', 'Sr. Gerente', '1/1/2002', 'ABC125'),
    (4, '00000012', 'Sr. Gerente', '1/1/2002', 'ABC125'),
    (5, '00000012', 'Sr. Gerente', '1/1/2002', 'ABC125ZZ'),
    (6, '00000012', 'Director', '1/1/2006', 'ABC126'),
    (7, '00000012', 'Director', '1/1/2006', 'ABC126'),
    (8, '00000012', 'Sr. Director', '1/1/2009', 'ABC129ZZ');

-- Eliminar filas que son duplicados ciertos
DELETE FROM @SomeData
WHERE RowID IN (
    SELECT compare.RowID
    FROM @SomeData main
    LEFT OUTER JOIN @SomeData compare ON main.EmpID = compare.EmpID
        AND main.RowID = compare.RowID - 1
    WHERE main.PositionTitle = compare.PositionTitle
        AND main.PositionID = compare.PositionID
        AND main.PositionEffDate = compare.PositionEffDate
);

-- Renumerar los RowIDs utilizando una CTE y la función ROW_NUMBER()
WITH newPH AS (
    SELECT RowID, ROW_NUMBER() OVER (ORDER BY RowID ASC) AS [newRowID]
    FROM @SomeData
)
UPDATE newPH SET RowID = newRowID;

-- Eliminar las filas duplicadas restantes, manteniendo la primera fila que coincide
DELETE FROM @SomeData
WHERE RowID IN (
    SELECT compare.RowID
    FROM @SomeData main
    LEFT OUTER JOIN @SomeData compare ON main.EmpID = compare.EmpID
        AND main.RowID = compare.RowID - 1
    WHERE main.PositionTitle = compare.PositionTitle
        AND main.PositionEffDate = compare.PositionEffDate
);

-- Ver el resultado final
SELECT 'Arreglado' AS [Descripción], * FROM @SomeData;

En este ejemplo, comenzamos configurando una variable de tabla con algunos datos que contienen duplicados y duplicados inciertos. Luego eliminamos las filas que son duplicados ciertos basados en el título del puesto, la fecha efectiva y el ID del puesto.

A continuación, utilizamos una CTE y la función ROW_NUMBER() para renumerar los RowIDs en orden secuencial. Esto asegura que los números de IDENTITY() sean consistentes y se puedan utilizar para operaciones adicionales.

Finalmente, eliminamos las filas duplicadas restantes, manteniendo solo la primera fila que coincide basada en el título del puesto y la fecha efectiva. El resultado es un conjunto de datos limpio y arreglado.

Al utilizar este truco, puede gestionar eficientemente las tareas de limpieza de datos en SQL Server sin recurrir a cursores. Proporciona un enfoque más simplificado y optimizado para manejar comparaciones y eliminaciones.

Recuerde utilizar punto y coma después de sus declaraciones al trabajar con CTEs o declaraciones MERGE para evitar cualquier ambigüedad en el código.

¡Pruebe esta técnica en su próximo proyecto de limpieza de datos y vea cómo simplifica su flujo de trabajo!

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.