Comparaciones fonéticas utilizando el Metaphone
En SQL Server existen dos funciones que sirven para realizar comparaciones fonéticas de nombres o palabras de acuerdo al sonido que emiten. Estas funciones llamadas SOUNDEX y DIFFERENCES provienen del algoritmo fonético Soundex, desarrollado por Robert Russell y Margaret Odell, que indexa los nombres de acuerdo a su sonido en inglés.
En SQL la función Soundex genera el sonido que arrojar una palabra, mientras que Differences realiza una comparación entre los sonidos de dos palabras a la que se le aplica el Soundex internamente.
El Soundex tiene ciertas deficiencias, que no lo hace tan efectivo, por ejemplo, las consonantes que suenan parecido devuelven el mismo valor (B, F y P devuelven 1) y las vocales pueden afectar la codificación, sin embargo es poco utilizable.
Por esta razón, Lawrence Phillips desarrolla el algoritmo Metaphone en respuesta a las deficiencias que presentaba el primero. Este fue publicado en 1990 y se encuentra publicado en distintos lenguajes, C, PHP, SQL, etc para indexar palabras por su sonido en el idioma inglés.
Este ya viene integrado en PHP, esperamos que pronto sea integrado al SQL Server como se hizo con el Soundex, para así ayudar un poco a los desarrolladores. El autor más tarde desarrolló una nueva versión del algoritmo, al que llamó "Double Metaphone", que produce resultados más exactos que el original
Debajo el ejemplo del código MetaPhone, para su uso recomiendo crearlo en la base de datos master, para que el mismo pueda ser implementado en llamado desde cualquier base de datos:
USE [master]
GO
/****** Object: UserDefinedFunction [dbo].[Metaphone] Script Date: 06/30/2011 11:57:07 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[Metaphone](@str as varchar(70))
RETURNS VARCHAR (25)
/*
Metaphone Algorithm
Created by Lawrence Philips.
Metaphone presented in article in "Computer Language" December 1990 issue.
Translated into t-SQL by Keith Henry (keithh_AT_lbm-solutions.com)
*********** BEGIN METAPHONE RULES ***********
Lawrence Philips' RULES follow:
The 16 consonant sounds:
|--- ZERO represents "th"
|
B X S K J T F H L M N P R 0 W Y
Drop vowels
Exceptions:
Beginning of word: "ae-", "gn", "kn-", "pn-", "wr-" ----> drop first letter
Beginning of word: "x" ----> change to "s"
Beginning of word: "wh-" ----> change to "w"
Beginning of word: vowel ----> Keep it
Transformations:
B ----> B unless at the end of word after "m", as in "dumb", "McComb"
C ----> X (sh) if "-cia-" or "-ch-"
S if "-ci-", "-ce-", or "-cy-"
SILENT if "-sci-", "-sce-", or "-scy-"
K otherwise, including in "-sch-"
D ----> J if in "-dge-", "-dgy-", or "-dgi-"
T otherwise
F ----> F
G ----> SILENT if in "-gh-" and not at end or before a vowel
in "-gn" or "-gned"
in "-dge-" etc., as in above rule
J if before "i", or "e", or "y" if not double "gg"
K otherwise
H ----> SILENT if after vowel and no vowel follows
or after "-ch-", "-sh-", "-ph-", "-th-", "-gh-"
H otherwise
J ----> J
K ----> SILENT if after "c"
K otherwise
L ----> L
M ----> M
N ----> N
P ----> F if before "h"
P otherwise
Q ----> K
R ----> R
S ----> X (sh) if before "h" or in "-sio-" or "-sia-"
S otherwise
T ----> X (sh) if "-tia-" or "-tio-"
0 (th) if before "h"
silent if in "-tch-"
T otherwise
V ----> F
W ----> SILENT if not followed by a vowel
W if followed by a vowel
X ----> KS
Y ----> SILENT if not followed by a vowel
Y if followed by a vowel
Z ----> S
*/
AS
BEGIN
DECLARE @Result VARCHAR(25),
@str3 CHAR(3),
@str2 CHAR(2),
@str1 CHAR(1),
@strp CHAR(1),
@strLen TINYINT,
@cnt TINYINT
SET @strLen = LEN(@str)
SET @cnt = 1
SET @Result = ''
--Process beginning exceptions
set @str2 = left(@str,2)
if @str2 in ('ae', 'gn', 'kn', 'pn', 'wr')
begin
set @str = right(@str , @strLen - 1)
set @strLen = @strLen - 1
end
if @str2 = 'wh'
begin
set @str = 'w' + right(@str , @strLen - 2)
set @strLen = @strLen - 1
end
set @str1 = left(@str,1)
if @str1 = 'x'
begin
set @str = 's' + right(@str , @strLen - 1)
end
if @str1 in ('a','e','i','o','u')
begin
set @str = right(@str , @strLen - 1)
set @strLen = @strLen - 1
set @Result = @str1
end
while @cnt <= @strLen
begin
set @str1 = substring(@str,@cnt,1)
if @cnt <> 1
set @strp = substring(@str,(@cnt-1),1)
else set @strp = ' '
if @strp <> @str1
begin
set @str2 = substring(@str,@cnt,2)
if @str1 in ('f','j','l','m','n','r')
set @Result = @Result + @str1
if @str1 = 'q' set @Result = @Result + 'k'
if @str1 = 'v' set @Result = @Result + 'f'
if @str1 = 'x' set @Result = @Result + 'ks'
if @str1 = 'z' set @Result = @Result + 's'
if @str1 = 'b'
if @cnt = @strLen
if substring(@str,(@cnt - 1),1) <> 'm'
set @Result = @Result + 'b'
else
set @Result = @Result + 'b'
if @str1 = 'c'
if @str2 = 'ch' or substring(@str,@cnt,3) = 'cia'
set @Result = @Result + 'x'
else
if @str2 in ('ci','ce','cy') and @strp <> 's'
set @Result = @Result + 's'
else set @Result = @Result + 'k'
if @str1 = 'd'
if substring(@str,@cnt,3) in ('dge','dgy','dgi')
set @Result = @Result + 'j'
else set @Result = @Result + 't'
if @str1 = 'g'
if substring(@str,(@cnt - 1),3) not in ('dge','dgy','dgi','dha','dhe','dhi','dho','dhu')
if @str2 in ('gi', 'ge','gy')
set @Result = @Result + 'j'
else
if (@str2 <> 'gn') or ((@str2 <> 'gh') and ((@cnt + 1) <> @strLen))
set @Result = @Result + 'k'
if @str1 = 'h'
if (@strp not in ('a','e','i','o','u')) and (@str2 not in ('ha','he','hi','ho','hu'))
if @strp not in ('c','s','p','t','g')
set @Result = @Result + 'h'
if @str1 = 'k'
if @strp <> 'c'
set @Result = @Result + 'K'
if @str1 = 'p'
if @str2 = 'ph'
set @Result = @Result + 'f'
else
set @Result = @Result + 'p'
if @str1 = 's'
if substring(@str,@cnt,3) in ('sia','sio') or @str2 = 'sh'
set @Result = @Result + 'x'
else set @Result = @Result + 's'
if @str1 = 't'
if substring(@str,@cnt,3) in ('tia','tio')
set @Result = @Result + 'x'
else
if @str2 = 'th'
set @Result = @Result + '0'
else
if substring(@str,@cnt,3) <> 'tch'
set @Result = @Result + 't'
if @str1 = 'w'
if @str2 not in('wa','we','wi','wo','wu')
set @Result = @Result + 'w'
if @str1 = 'y'
if @str2 not in('ya','ye','yi','yo','yu')
set @Result = @Result + 'y'
end
set @cnt = @cnt + 1
end
RETURN UPPER(@Result)
END
Enlaces:
Comentarios
La fonetización en español, interesante tema cierto?
SoundEsp ya esta listo y casi en linea para pruebas; Fonetizador en español.
http://soundesp.somee.com/Fonetizador.asp
Saludos.