Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Soundex Alternatif
#1
Merhabalar,

Bir ihtiyaca bineaen dün yazdığım soundex alternatifi, kelimelerin benzeşme oranını bulan fonksiyonumu incelemek, eleştirmek ve katkıda bulunmak isterseniz düşüncesiyle burada paylaşıyorum. Fonkisyonun sonucu yüzdesel benzeşme oranını temsil ediyor.
@engkarsilastir parametersi ile seçeneğe bağlı olarak türkçe karakterleri eng ile değiştirip daha yakın sonuçlar elde etmeyi planladım.
Yaklaşım olarak pozitivist bir yaklaşım sergiledim. 
Dönen resultsette order by descending ile benzeşme oranına göre paging yaparak belli bir adet kaydı çekiyorum uygulamama.
Yada Filitrenizin benzeşme oranına göre tabloyu sorgulayabilirsiniz. Örneğin benzeşme oranı %70 ve üzeri sorgulanabilir.
Performansı Nasıl ki ?;
sunucu İşletim sistemi, sunucu donanım ve mimarisi, sql serverın versiyonu ve lisans türü tabiki sonucu etkilemekle beraber, 
kendi lokal sunucumda 30bin kayıtlık tablomda index-siz bir sütunda 8 saniyede istediğim sonucu getirdi.
Sonuçta bir zaman maliyeti olacağı aşikar, Gülü seven dikenine katlanır dimi.
Ancak bunu ne kadar aşağıya çekersek kar tabi.
Belki bu topluluğun da katkılarıyla Türkçemize özgü daha güzel bir fonksiyon çıkarabiliriz beraber.

Yaptığım test sonucu aşağıdadır.

aqFNkM.jpg


create function dbo.fn_benzesme( @ara varchar(30), @bul varchar(30) , @engkarsilastir bit )
returns tinyint
as
begin
declare  
@i int = 0,
@harf varchar(1)
if @ara = @bul return 100
if  abs(len(@bul)-len(@ara)) > len(@ara)/2 return 0
if @engkarsilastir = 1
begin 
SET @ara = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@ara,'Ğ','G'),'Ü','U'),'İ','I'),'Ş','S'),'Ö','O'),'Ç','C')
SET @bul = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@bul,'Ğ','G'),'Ü','U'),'İ','I'),'Ş','S'),'Ö','O'),'Ç','C')
end
declare @harft table (string varchar(30), harf varchar(1) , INDEX IX1 (string) , INDEX IX2 (harf) )
set @i   = 1
while @i <= len(@ara)
begin
set @harf = substring(@ara,@i,1);
insert into @harft values (@ara,@harf) 
set @i = @i+1
end
set @i   = 1
SET @harf = ''
while @i <= len(@bul)
begin
set @harf = substring(@bul,@i,1);
insert into @harft values (@bul,@harf) 
set @i = @i+1
end
SELECT @i = 
SUM(CASE 
WHEN  isnull(arasay,0) = isnull(bulsay,0) then 100.0
WHEN  isnull(arasay,0)>0 and isnull(bulsay,0)>0 then 75.0
ELSE  0  end 
+ iif(left(@ara,1)=left(@bul,1),25,0)
+ iif(right(@ara,1)=right(@bul,1),15,0)
)  / convert(float,COUNT(*))

from 
(
select string,harf,count(*) arasay
from @harft
where string = @ara
group by  string,harf
) bul 
full outer join 
(
select string,harf,count(*) bulsay
from @harft
where string = @bul
group by  string,harf
) string on string.harf = bul.harf
SET @i = ISNULL(@i,0)
return CASE when @i<0 then 0 when @i>=100 then 99 else @i end
end
go
DECLARE @T TABLE(ara varchar(30) , bul varchar(30))
INSERT INTO @T VALUES ('SADULLAH','ABDULLAH'),('HAKAN','HASAN'),('İSTANBUL','ISTAMBUL'),('SMAIL','İSMAİL'),('ŞEYMA','SEYMA'),('ALİ CAN','QALI ÇAN'),('FADİME','FATIMA'),('OSMANLI','OSMANCIK'),('KAYIHAN','AYHAN'),('AYŞE','ASYA'),('GELİVER','GELDİM')
SELECT * , dbo.fn_benzesme(ARA,BUL , 0) TRK, dbo.fn_benzesme(ARA,BUL , 1) ENG , DIFFERENCE(ARA,BUL) SOUNDEX_ FROM @T 

Herhangi bir insan bilgisayarın anlayabileceği kod yazabilir.  İyi programcılar ise insanların da anlayabileceği kodlar yazarlar. 
Martin Fowler / Refactoring 
Cevapla




Konuyu Okuyanlar: 1 Ziyaretçi