Tenemos el siguiente problema: en una tabla hay una columna donde se guardan números de teléfono, los cuales pueden estar repetidos y queremos que haya una sola fila por cada número de teléfono. Pero el problema es que esos números de teléfono pueden estar escritos de varias maneras, por ejemplo:
- 11-555-9090
- (11)555-9090
- 115559090
Captura 1. Si haces clic en la imagen la verás más grande
En la Captura 1. vemos el Identificador y el Número de Teléfono que existen en siete filas de una tabla. Solamente el Número de Teléfono de la fila que tiene Identificador igual a 4 no está repetido. En todas las demás filas hay simplemente variaciones de los mismos números, escritos con diferentes formatos.
Entonces, ¿cómo podemos saber cuales filas tienen números de teléfono repetidos?
Primero, buscaremos cuales son los números repetidos, estén escritos en el formato que sea.
Para ellos usaremos la función REPLACE() la cual nos permite reemplazar una carácter (o varios caracteres) por otro carácter (o por varios caracteres). En nuestro caso reemplazaremos por un carácter vacío.
Listado 1.
SELECT REPLACE(ALU_TELEFO, '(', '') FROM ALUMNOS
Al ejecutar el Listado 1. veremos algo como:
Captura 2. Si haces clic en la imagen la verás más grande
Si observas la Captura 2. notarás que han desaparecido los paréntesis izquierdos. Seguimos refinando nuestro SELECT.
Listado 2.
SELECT REPLACE(REPLACE(ALU_TELEFO, '(', ''), ')', '') FROM ALUMNOS
Captura 3. Si haces clic en la imagen la verás más grande
Si observas la Captura 3. notarás que han desaparecido los paréntesis izquierdos y también los paréntesis derechos. Seguimos refinando nuestro SELECT.
Listado 3.
SELECT REPLACE(REPLACE(REPLACE(ALU_TELEFO, '(', ''), ')', ''), '-', '') FROM ALUMNOS
Captura 4. Si haces clic en la imagen la verás más grande
Como ya habrás visto, en la Captura 4. no hay ni paréntesis ni guiones. Así que buscar duplicados ahora ya es más fácil.
Listado 4.
SELECT REPLACE(REPLACE(REPLACE(ALU_TELEFO, '(', ''), ')', ''), '-', '') FROM ALUMNOS GROUP BY REPLACE(REPLACE(REPLACE(ALU_TELEFO, '(', ''), ')', ''), '-', '') HAVING COUNT(*) >= 2
El SELECT del Listado 4. también podríamos haberlo escrito de forma más simplificada así:
Listado 5.
SELECT REPLACE(REPLACE(REPLACE(ALU_TELEFO, '(', ''), ')', ''), '-', '') FROM ALUMNOS GROUP BY 1 HAVING COUNT(*) >= 2
En ambos casos obtendremos el mismo resultado:
Captura 5. Si haces clic en la imagen la verás más grande
Donde podemos ver los números que se repiten. Ahora bien, ya sabemos cuales son los números que se repiten, pero ¿en cuáles filas están? Esa información la obtendremos mediante el siguiente SELECT
Listado 6.
SELECT ALU_IDENTI, ALU_TELEFO FROM ALUMNOS WHERE REPLACE(REPLACE(REPLACE(ALU_TELEFO, '(', ''), ')', ''), '-', '') IN (SELECT REPLACE(REPLACE(REPLACE(ALU_TELEFO, '(', ''), ')', ''), '-', '') FROM ALUMNOS GROUP BY 1 HAVING COUNT(*) >= 2)
Captura 6. Si haces clic en la imagen la verás más grande
Donde la única fila que no aparece es la que tiene Identificador igual a 4, porque esa fila no tiene un Número de Teléfono que esté repetido.
Como seguramente te habrás dado cuenta mirando los SELECTs anteriores, usamos una función REPLACE() por cada carácter que deseamos extraer. Un carácter, una función REPLACE(); dos caracteres, dos funciones REPLACE(); tres caracteres, tres funciones REPLACE().
Supongamos ahora que queremos dejar en nuestra tabla solamente la primera fila de cada número. O sea que quisiéramos obtener esto:
Captura 7. Si haces clic en la imagen la verás más grande
¿Cómo lo podemos conseguir?
Listado 7.
DELETE FROM ALUMNOS T1 WHERE NOT EXISTS (SELECT T2.ALU_IDENTI FROM ALUMNOS T2 WHERE REPLACE(REPLACE(REPLACE(T1.ALU_TELEFO, '(', ''), ')', ''), '-', '') = REPLACE(REPLACE(REPLACE(T2.ALU_TELEFO, '(', ''), ')', ''), '-', '') AND T1.ALU_IDENTI > T2.ALU_IDENTI)
Conclusión:
Hay varias técnicas que podemos usar para conocer si hay números duplicados aunque estén escritos con diferentes formatos, y para borrarlos en caso de necesidad. En este artículo se mostró una de esas técnicas, la cual al autor le parece mucho más sencilla que, por ejemplo, escribir un stored procedure que realice la misma tarea.
Artículos relacionados:
Agrupando por una columna … y viendo todas las demás columnas
Obteniendo la primera fila de cada grupo
Deja un comentario