La función SOUNDEX es un algoritmo fonético que sirve principalmente para filtran o indexar nombres de acuerdo a la forma en que se pronuncian en inglés. El algoritmo es bastante maduro, por no decir viejo, ya que tiene más de 100 años. SOUNDEX tiene la ventaja de que esta implementados en prácticamente todas las bases de datos relacionales y alguna base de datos no relacionales. El algoritmo genera un código de 4 caracteres que inicia con una letra seguido de 3 dígitos.
Primer ejemplo de uso de SOUNDEX
SELECT Nombre
, SOUNDEX(Nombre) AS SoundexIdx
FROM (VALUES
('Javier'),
('Jaever'),
('Juvier'),
('Javeir'),
('Javvier'),
('Jeffrey'),
('Xavier')
) AS Nombres(Nombre);
Con el ejemplo puedes notar que el algoritmo trata de agrupar bajo el mismo código diferentes sonidos que ingles suenan parecido a Javier, pero no Xavier. El resultado de la consulta es:
Nombre | SoundexIdx |
Javier | J160 |
Jaever | J160 |
Juvier | J160 |
Javeir | J160 |
Javvier | J160 |
Jeffrey | J160 |
Xavier | X160 |
Como sigue la fonética inglesa (y tampoco es muy avanzado), no necesariamente se ajusta al español o castellano, pero aun así podemos usarlo como una aproximación.
Consultas para analisis/agrupación
Si quieres darle un uso mas avanzado, puedes por ejemplo extraer del INE (Instituto Nacional de Estadística/España) los nombres mas frecuentes de los recién nacidos. Puedes bajar las versiones hasta el 2018 de INE Nombres Recién Nacidos. Con eso puedes crear la siguiente consulta:
SELECT *
, SOUNDEX(Nombre) AS SoundexIdx
FROM (VALUES
('HUGO', 3800, 'NIÑOS'),
('LUCAS', 3617, 'NIÑOS'),
...
('NURIA', 307, 'NIÑAS'),
('YASMIN', 304, 'NIÑAS'),
('MALAK', 298, 'NIÑAS')
) AS Nombres(Nombre, Nacimientos, Sexo)
ORDER BY Nacimientos;
Esta consulta puede servir para agrupar los datos y usando alguna herramienta analítica pueden visualizarse familias de nombres relacionados. Usando el TreeMap de Tableu, por ejemplo:

Aplicado al padrón electoral del Costa Rica, poco menos de 3.4 Millones de filas, la siguiente consulta genera el siguiente mapa.
SELECT Nombre, SOUNDEX(Nombre) AS SKey
, COUNT(*) AS NCount
, SUM(COUNT(*))
OVER(PARTITION BY SOUNDEX(Nombre) ORDER BY COUNT(*)
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS SCount
FROM dbo.Padron
GROUP BY Nombre
HAVING COUNT(*)>1000
ORDER BY 4 DESC, 2,3 DESC,1;

La concentración de nombres compuestos en Costa Rica que usan Maria y Jose es altísima, por eso los valores M600 y J200 tienen 139,028 y 89,274 filas respectivamente, aunque es probable que en años recientes esto haya cambiado.
Soundex como Filtro
Pero lo cierto es que el uso de esta función rara vez es analítico, sino más bien para filtrar o indexar nombres. Por ejemplo, el siguiente código agrega una columna al padrón electoral y un índice:
ALTER TABLE dbo.Padron
ADD SoundexNombre AS SOUNDEX(Nombre) PERSISTED
-- 42 Seg.
CREATE NONCLUSTERED INDEX IDX_SoundexPadron
ON dbo.Padron(SoundexNombre)
INCLUDE (Nombre);
La ventaja de este índice es que una consulta como la siguiente:
SELECT TOP 10 Nombre, COUNT()
FROM dbo.Padron
WHERE SOUNDEX(Nombre)='J160'
GROUP BY NOMBRE ORDER BY COUNT() DESC;
Se beneficia del índice, aun cuando no haga uso directo de la columna SoundexNombre, produce un plan bastante mas eficiente. La mayoría del costo esta en la agregación de los datos y en Sort para el Top.

En futuros posteos voy a hablar de alternativas del Soundex, particularmente el algoritmo Metaphone y luego moverme a temas más específicos de búsquedas difusas.
Deja una respuesta