VALIDAR REGISTROS DUPLICADOS DE UNA COLUMNA, TOMANDO VARIAS POSICIONES DE LA CADENA

Daniel Polvo
06 de Diciembre del 2013
QUE TAL, ESPERO SE ENCUENTREN MUY BIEN, REQUIERO DE SU AYUDA PARA VALIDAR REGISTROS DUPLICADOS E INSERTAR EN LA MISMA TABLA DONDE SE ENCUENTRAN DICHOS REGISTROS LA LETRA "S" SI HAN ENCONTRADO REGISTROS DUPLICADOS Y UNA "N" EN CASO CONTRARIO. AL PRINCIPIO TENGO QUE VALIDAR TODA LA CADENAS, POSTERIORMENTE 13 POSICIONES, DESPUÉS 11, Y POR ULTIMO 10 POSICIONE.

YA LO HE LOGRADO CON UN CURSOR, PERO AL SUBSTRAER 13 POSICIONES NO LOGRO QUE FUNCIONE CORRECTAMENTE, APENAS ESTOY APRENDIENDO ESTA TECNOLOGÍA ES POR ESO QUE ESTOY ATORADO CON ESTE DETALLE, ESPERO PUEDAN AUXILIARME, AÑADO CÓDIGO:



DECLARE @MATCHCODE VARCHAR(50)

-- Declaración del cursor
DECLARE cMATCHCODE CURSOR FOR
SELECT DISTINCT SUBSTRING(MATCHCODE,1,13) FROM PROCESO_TAB
WHERE SUBSTRING(MATCHCODE,1,13) In
(SELECT SUBSTRING(MATCHCODE,1,13) FROM PROCESO_TAB As DUPLICADO_13
GROUP BY SUBSTRING(MATCHCODE,1,13) HAVING Count(1) > 1 )
ORDER BY SUBSTRING(MATCHCODE,1,13)
FOR UPDATE

-- Apertura del cursor
OPEN cMATCHCODE

-- Lectura de la primera fila del cursor
FETCH cMATCHCODE INTO @MATCHCODE

WHILE (@@FETCH_STATUS = 0 )

BEGIN
UPDATE PROCESO_TAB
SET M13 = 'S'
WHERE SUBSTRING(MATCHCODE,1,13) = @MATCHCODE

-- Lectura de la siguiente fila del cursor
FETCH cMATCHCODE INTO @MATCHCODE
END

BEGIN
UPDATE PROCESO_TAB
SET M13 = 'N'
WHERE SUBSTRING(MATCHCODE,1,13) @MATCHCODE

-- Lectura de la siguiente fila del cursor
FETCH cMATCHCODE INTO @MATCHCODE
END

-- Cierre del cursor
CLOSE cMATCHCODE
-- Liberar los recursos
DEALLOCATE cMATCHCODE

Sara
12 de Agosto del 2026

Hola,

Antes de seguir peleando con el cursor: para detectar duplicados no hace falta procesar fila a fila, se puede resolver con una única sentencia usando funciones de ventana, mucho más rápido y sin la complejidad de mantener un bucle. La idea general, adaptándola a tus tres longitudes (cadena completa, 13, 11 y 10 posiciones):

UPDATE t
SET t.marca_duplicado = CASE WHEN conteo.total > 1 THEN 'S' ELSE 'N' END
FROM tu_tabla t
CROSS APPLY (
    SELECT COUNT(*) AS total
    FROM tu_tabla t2
    WHERE LEFT(t2.cadena, 13) = LEFT(t.cadena, 13)
) conteo;

Cambia el 13 por la longitud que toque validar en cada pasada (13, 11, 10), y LEFT(cadena, n) por SUBSTRING si necesitas una posición intermedia en vez de desde el principio. El CROSS APPLY hace, para cada fila, un conteo de cuántas filas comparten esos mismos primeros N caracteres; si el conteo es mayor que 1, hay al menos otra fila igual y marcas 'S'.

También se puede hacer sin CROSS APPLY, con COUNT(*) OVER (PARTITION BY LEFT(cadena, 13)), que es funcionalmente equivalente y en muchos casos más rápido porque SQL Server puede resolverlo en una sola pasada sin correlacionar subconsultas:

WITH marcado AS (
    SELECT *, COUNT(*) OVER (PARTITION BY LEFT(cadena, 13)) AS veces
    FROM tu_tabla
)
UPDATE marcado SET marca_duplicado = CASE WHEN veces > 1 THEN 'S' ELSE 'N' END;

Con cualquiera de las dos formas te ahorras el cursor por completo: en SQL Server, salvo casos muy concretos, si te encuentras escribiendo un cursor casi siempre hay una forma basada en conjuntos (como estas) que resuelve lo mismo sin procesar registro a registro.

Sara