SoundexESP
From PostgreSQL wiki
Jump to navigationJump to searchCompute string soundex spanish
Works with PostgreSQL
Tested on 9.0, 9.1. Probably works in earlier versions
Written in
PL/pgSQL
Depends on
Nothing
Soundex Spanish is a function written to calculate soundex codes for spanish languages.
The soundex algorithm is written for english language, so it is not advisable to use it in other languages.
In my personal case, I needed a spanish version of the soundex algorithm, so, based on lfer work Soundex en Español, I made the PL/pgSQL version for the Spanish Soundex Algorithm.
Thanks to Grupo Vesica.
Hope this helps someone else:
-- oliver mazariegos http://www.grupovesica.com
CREATE OR REPLACE FUNCTION soundexesp(input text) RETURNS text
IMMUTABLE STRICT COST 500 LANGUAGE plpgsql
AS $$
DECLARE
soundex text='';
-- para determinar la primera letra
pri_letra text;
resto text;
sustituida text ='';
-- para quitar adyacentes
anterior text;
actual text;
corregido text;
BEGIN
-- devolver null si recibi un string en blanco o con espacios en blanco
if length(trim(input))= 0 then
return null;
end if;
-- 1: LIMPIEZA:
-- pasar a mayuscula, eliminar la letra "H" inicial, los acentos y la enie
-- 'holá coñó' => 'OLA CONO'
input=translate(ltrim(trim(upper(input)),'H'),'ÑÁÉÍÓÚÀÈÌÒÙÜ','NAEIOUAEIOUU');
-- eliminar caracteres no alfabéticos (números, símbolos como &,%,",*,!,+, etc.
input=regexp_replace(input, '[^a-zA-Z]', '', 'g');
-- 2: PRIMERA LETRA ES IMPORTANTE, DEBO ASOCIAR LAS SIMILARES
-- 'vaca' se convierte en 'baca' y 'zapote' se convierte en 'sapote'
-- un fenomeno importante es GE y GI se vuelven JE y JI; CA se vuelve KA, etc
pri_letra =substr(input,1,1);
resto =substr(input,2);
CASE
when pri_letra in ('V') then
sustituida='B';
when pri_letra in ('Z','X') then
sustituida='S';
when pri_letra in ('G') and substr(input,2,1) in ('E','I') then
sustituida='J';
when pri_letra in('C') and substr(input,2,1) not in ('H','E','I') then
sustituida='K';
else
sustituida=pri_letra;
end case;
--corregir el parametro con las consonantes sustituidas:
input=sustituida || resto;
-- 3: corregir "letras compuestas" y volverlas una sola
input=replace(input,'CH','V');
input=replace(input,'QU','K');
input=replace(input,'LL','J');
input=replace(input,'CE','S');
input=replace(input,'CI','S');
input=replace(input,'YA','J');
input=replace(input,'YE','J');
input=replace(input,'YI','J');
input=replace(input,'YO','J');
input=replace(input,'YU','J');
input=replace(input,'GE','J');
input=replace(input,'GI','J');
input=replace(input,'NY','N');
-- para debug: --return input;
-- EMPIEZA EL CALCULO DEL SOUNDEX
-- 4: OBTENER PRIMERA letra
pri_letra=substr(input,1,1);
-- 5: retener el resto del string
resto=substr(input,2);
--6: en el resto del string, quitar vocales y vocales fonéticas
resto=translate(resto,'@AEIOUHWY','@');
--7: convertir las letras foneticamente equivalentes a numeros (esto hace que B sea equivalente a V, C con S y Z, etc.)
resto=translate(resto, 'BPFVCGKSXZDTLMNRQJ', '111122222233455677');
-- así va quedando la cosa
soundex=pri_letra || resto;
--8: eliminar números iguales adyacentes (A11233 se vuelve A123)
anterior=substr(soundex,1,1);
corregido=anterior;
FOR i IN 2 .. length(soundex) LOOP
actual = substr(soundex, i, 1);
IF actual <> anterior THEN
corregido=corregido || actual;
anterior=actual;
END IF;
END LOOP;
-- así va la cosa
soundex=corregido;
-- 9: siempre retornar un string de 4 posiciones
soundex=rpad(soundex,4,'0');
soundex=substr(soundex,1,4);
-- YA ESTUVO
return soundex;
END;
$$
Example
db=#select soundexesp('ordoñez'), soundexesp('ordónez'), soundexesp('ordondes'), soundexesp('karla'), soundexesp('CARLA'); O635 | O635 | O635 | K640 | K640