Mysql için count_str() “kelimedeki karakterin adedi” fonksiyonu
Bir önceki yazıda MySQL için split_str() fonksiyonunu oluşturmuştuk. Kelimeleri verdiğimiz karaktere göre bölüyordu. Amacımız; ad ve soyad değerleri tek bir sütunda isim olarak verildiğinde bu isim bilgisinden ad ve soyadı ayrıştırabilmek idi. split_str() fonksiyonu datayı istediğimiz karaktere göre (örneğin boşluk karakteri) bölebiliyor ve ortaya çıkan gruplardan hangisini görmek istiyorsak onu almamızı sağlıyor. Ama problemimiz için bu yeterli değil. Çünkü isimler her zaman “Fehim Tabak” gibi bir ad ve bir soyaddan oluşmuyor. İki ad ve bir soyad, hatta kulakları çınlasın sevgili arkadaşım “Yusuf Ziya Bektaş Köseoğlu” gibi üç ad ve bir soyad da olabiliyor. Böyle bir bilgiden soyadı ve adı ayrıştırabilmek için “en son kelime soyaddır” ve “en son kelime hariç diğerleri addır” diyebilmek gerek. Aşağıda yazacağımız count_str() fonksiyonu işte bu noktada devreye giriyor.
CREATE FUNCTION COUNT_STR(
x VARCHAR(255),
delim VARCHAR(12)
)
RETURNS INT
RETURN LENGTH(x)-LENGTH(REPLACE(x,delim,”));
Bu fonksiyon parametre olarak verdiğimiz karakterin yine parametre olarak verdiğimiz kelimenin içerisinde kaç kere geçtiğini döndürüyor. Boşluk ‘ ‘ karakteri ilgili alanda kaç kere var diye kullanırsak ‘Fehim Tabak’ için 1, ‘Yusuf Ziya Bektaş Köseoğlu’ için 3 döndürür. Bu sayının bir fazlası bize o alanda kaç kelimelik bir bilgi olduğunu yani ismin kaç kelimeden oluştuğunu döndürür.
Buraya kadar güzel, isim bilgisinden soyadı hanesini bir önceki yazıda oluşturduğumuz split_str() ve burada bahsettiğimiz count_str() fonksiyonlarıyla şu şekilde çekebiliriz:
split_str(isim,’ ‘,count_str(isim,’ ‘)+1)
Bu ‘isim hanesini boşluklardan ayır, içindeki kelime sayısı kaç ise sonuncu kelimeyi döndür‘ işlevi görür. Fakat eğer olur da isim yerine sadece ad yazmışlarsa yani tek kelime kullanılmışsa (ki elimdeki datada böyle kayıtlar mevcut) küçük bir case yazmak lazım:
case count_str(isim,’ ‘)+1
when 1 then ”
else split_str(isim,’ ‘,count_str(isim,’ ‘)+1)
end
Bu ‘isim hanesi tek kelime ise birşey döndürme, diğer durumlarda isim hanesini boşluklardan ayır, içindeki kelime sayısı kaç ise sonuncu kelimeyi döndür‘ işlevi görür. İşte bu şekilde varsa soyadı hanesini başarılı bir şekilde elde etmiş olduk. Ama ad hanesi için biraz daha terlemek icab ediyor. İsimler iki kelimeden ibaret olsaydı zaten herşey en başında da kolaydı fakat mesele üç hatta dört kelimeli isimleri ad ve soyad hanesinden ayırmak. Bunun için sadece case when yapısını biraz büyütmek lazım o kadar. Şu aşağıdaki yapı ad ve soyadı birbirinden ayıracaktır:
case count_str(isim,’ ‘)+1
when 1 then split_str(isim,’ ‘,1)
when 2 then split_str(isim,’ ‘,1)
when 3 then concat(split_str(isim,’ ‘,1), ‘ ‘, split_str(isim,’ ‘,2) )
when 4 then concat(split_str(isim,’ ‘,1), ‘ ‘, split_str(isim,’ ‘,2), ‘ ‘, split_str(isim,’ ‘,3) )
end as ad,
case count_str(isim,’ ‘)+1
when 1 then ”
else
split_str(isim,’ ‘,count_str(isim,’ ‘)+1)
end as soyad
Elimdeki data bir excel dosyasından alındığı için isim hanesinin başında veya sonunda boşluk karakterleri olabileceğini göz önüne almak gerek. Aslında bunu en başta düşünmemiştim fakat yukarıdaki kodu dataya uyguladığımda bazı satırlarda istediğim sonucu alamayınca fazladan boşluk karakterleri olduğunu anladım. Bu sorunu kalıcı olarak çözmek için data üzerinde trim() işlemi uygulayıp yukarıdaki sql’i ondan sonra çalıştırmak gerek ama hiç güncelleme yapmadan da trim fonksiyonunu sql’imizin içerisinde kullanarak meseleyi çözebiliriz. Performansı daha düşük olur tabi. Eğer datanız çoksa önce trim’leyip sonra ad ve soyadı ayrıştırmanız yerinde olacaktır. İşte sql’in trim’li hali şu şekilde:
case count_str(trim(isim),’ ‘)+1
when 1 then split_str(trim(isim),’ ‘,1)
when 2 then split_str(trim(isim),’ ‘,1)
when 3 then concat(split_str(trim(isim),’ ‘,1), ‘ ‘, split_str(trim(isim),’ ‘,2) )
when 4 then concat(split_str(trim(isim),’ ‘,1), ‘ ‘, split_str(trim(isim),’ ‘,2),’ ‘, split_str(trim(isim),’ ‘,3))
end as ad,
case count_str(trim(isim),’ ‘)+1
when 1 then ”
else
split_str(trim(isim),’ ‘,count_str(trim(isim),’ ‘)+1)
end as soyad
Bunu bir fonksiyon haline getirmek istersek:
create function adSoyad(
isim varchar(255),
hane varchar(5)
)
returns varchar(255)
return
case hane
when ‘ad’ then
case count_str(trim(isim),’ ‘)+1
when 1 then split_str(trim(isim),’ ‘,1)
when 2 then split_str(trim(isim),’ ‘,1)
when 3 then concat(split_str(trim(isim),’ ‘,1), ‘ ‘, split_str(trim(isim),’ ‘,2) )
when 4 then concat(split_str(trim(isim),’ ‘,1), ‘ ‘, split_str(trim(isim),’ ‘,2),’ ‘, split_str(trim(isim),’ ‘,3) )
end
when ‘soyad’ then
case count_str(trim(isim),’ ‘)+1
when 1 then ”
else
split_str(trim(isim),’ ‘,count_str(trim(isim),’ ‘)+1)
end
end
Bu fonksiyonu kullanmak gayet kolay olacaktır:
select adSoyad(isim,’ad’) as ad, adSoyad(isim,’soyad’) as soyad from tablo
İşte hepsi bu kadar..