Çox maraqlı bir hal yaranır. deməli bircə bu adda düzgün sıralamır. Başqa ağlıma gələnhalları yoxladım işləyir düzgün. Aşağıdakı nümunəyə baxın zəhmət olmasa. Hərflər ilə verəndə eyni halı düzgüz sıralayır. Ama ad soyad ata adı verəndə düz sıralamır.
[code]echo getOrderByAzeriLetters('a').PHP_EOL;
echo getOrderByAzeriLetters('ab').PHP_EOL;
echo getOrderByAzeriLetters('aba').PHP_EOL;
echo getOrderByAzeriLetters('abb').PHP_EOL;
echo getOrderByAzeriLetters('b').PHP_EOL;
echo getOrderByAzeriLetters('ba').PHP_EOL;
echo getOrderByAzeriLetters('bb').PHP_EOL;[/code]
belə düzgün sıralayır
[code]
echo getOrderByAzeriLetters('Abasova Mehriban Sahabbin').PHP_EOL;
echo getOrderByAzeriLetters('Abbasova Mehriban Sahabbin').PHP_EOL;
[/code]
ama bu halda yox.
Əla. Problem pow funksiyasında imiş. Ağlıma gəlməyib düzü. Test etdim xeyli data ilə tamamilə düzgün işlədi. Minnətdaram.
POW funksiyasında problem görürəm, artıqca düzgün hesablanmır. Uzun string üçün düzgün tətbiq edilməyib qısacası. Verdiyiniz iki ad soyadın order score-u tamamilə eyni alınır. Həm də 33pow34 kimi nəhəng ədədlər process edilir ki bu da heç yaxşı deyil calculation speed baxımdan.
Mən indi pow-u əvəz elədim cəm operatoru ilə.
Kodu və nəticəni paylaşıram
[php]
function getOrderByAzeriLetters($str) {
$captures = [1 => 'a', 2 => 'b', 3 => 'c', 4 => 'ç', 5 => 'd', 6 => 'e', 7 => 'ə', 8 => 'f',
9 => 'g', 10 => 'ğ', 11 => 'h', 12 => 'x', 13 => 'ı', 14 => 'i', 15 => 'j', 16 => 'k',
17 => 'q', 18 => 'l', 19 => 'm', 20 => 'n', 21 => 'o', 22 => 'ö', 23 => 'p', 24 => 'r',
25 => 's', 26 => 'ş', 27 => 't', 28 => 'u', 29 => 'ü', 30 => 'v', 31 => 'y', 32 => 'z'];
$str = mb_strtolower(trim($str));
$letters = mb_str_split($str);
$order = 0;
$i=0;
foreach($letters as $key => $char) {
if(in_array($char, $captures)) {
$position = array_search($char, $captures);
$division = $key === 0 ? 1 : ($key+$i*33);
$order += (32*$position) / $division;
$i++;
}
}
return $order;
}
echo getOrderByAzeriLetters('Abuşova Lamiyə Nizam').PHP_EOL;
echo getOrderByAzeriLetters('Abbasova Möminə Nizam').PHP_EOL;
echo getOrderByAzeriLetters('Abbasova Lamiyə Nizam').PHP_EOL;
echo getOrderByAzeriLetters('İsmayılova Möminə Nizam').PHP_EOL;
echo getOrderByAzeriLetters('İsmayılova Möminə İbrahim').PHP_EOL;
echo getOrderByAzeriLetters('İsmayılova Ülviyyə İbrahim').PHP_EOL;
[/php]
Output:
80.460855739996
64.516014812369
63.070509310542
511.35933715211
510.98574532239
514.87697337388
Göründüyü kimi output bu nümunədə verilən 6 ad-soyad üçün tamamilə doğru hesablanır. Ən kiçik 63-dür, Abbasova L.
Ən böyük isə 514 , İsmayılova Ü.
Salam. Bir müddət əvvəl sizin dediyiniz kimi elemişdim və həll etmişdi problemi, ama indi baxıram ki bəzi yerlerdə düzgün sıralamır.Funksiya belədir.
[code]function getOrderByAzeriLetters($str) {
$captures = [1 => 'a', 2 => 'b', 3 => 'c', 4 => 'ç', 5 => 'd', 6 => 'e', 7 => 'ə', 8 => 'f',
9 => 'g', 10 => 'ğ', 11 => 'h', 12 => 'x', 13 => 'ı', 14 => 'i', 15 => 'j', 16 => 'k',
17 => 'q', 18 => 'l', 19 => 'm', 20 => 'n', 21 => 'o', 22 => 'ö', 23 => 'p', 24 => 'r',
25 => 's', 26 => 'ş', 27 => 't', 28 => 'u', 29 => 'ü', 30 => 'v', 31 => 'y', 32 => 'z'];
$str = mb_strtolower(trim($str));
$letters = mb_str_split($str);
$order = 0;
foreach($letters as $key => $char) {
if(in_array($char, $captures)) {
$position = array_search($char, $captures);
$division = $key === 0 ? 1 : pow(33, $key);
$order += (32*$position) / $division;
}
}
return $order;
}[/code]
Məsələn
İsmayılova Ülviyyə İbrahim
İsmayılova Möminə Nizam
bu adları sıralayanda soyad eynidi deyə adlara keçir və M Ü dən öncə gəlməlidir ama düz sıralamır nədənsə.
orderi tapmaq üçün ad soyad ata adini oldugu kimi göndərirən funksiyaya.
Mən yazdığım kimi eləyəndə stabil işləmədi. Bir yerlərdə düzgün order eləmir. Sizin qeyd etdiyiniz kimi elədim işlədi tam dəqiq. Təşəkkür edirəm. Çox sağolun. Mysql də column string tipində eləyib order column nu order by verəndə integer ə cast elədim.
Belə bir yolla elədim. Düzgün sıralayır. string tipinde bir order column yaradırıq table da.
elementi save və update eləyəndə ad sahəsini aşağıdakı funksiyada keçirib nəticəni set edirəm order ə və select eləyəndə orderə görə sıralayıram.
[code] function getOrderByAzeriLetters($str) {
$captures = ['x' => 'h1', 'q' => 'k1'];
$str = mb_strtolower(trim($str));
$str = str_replace(array('(', ')', ' '), '', $str);
$letters = str_split($str);
$order = '';
foreach($letters as $char) {
if(array_key_exists($char, $captures)) {
$order .= $captures[$char];
} else {
$order .= $char;
}
}
return $order;
}[/code]
bir neçə dəfə test elədim səhf nəticə verən halla rastlaşmadım.
Əgər söhbət ədəd analoq sütundan gedirsə və hər ad üçün çəki müəyyən edilirsə, o da çox asandır, yəni bütöv söz üzrə orderby.
Mən yuxarıda yazan nümunədə funksiya score-u belə hesablayırdi
Ilk hərf = sıra nömrəsi.
Onun əvəzində başqa funksiya edə bilərsiz, kiçik sadə php funksiya.
Ilk hərf = 32*SIRA
Ikinci hərf = 32*SIRA/33
Üçüncü hərf = 32*SIRA/(33*33)
Və.s.
Alınan ədədlərin uzun yazılışli olmaması üçün hər hansı riyazi normalisation operator funksiyası da istifadə etmək olar. Ki store ediləcək ədəd uzun kəsr və ya çox böyük ədəd olmasın.(performansi salmamaq üçün)
Çox təşəkkür edirəm izah üçün. Bəli problem bizim əlifbanın ingilis əlifbasına nisbətən hansı hərf orderi fərqlidirsə problem həmən hərflərdə baş verir. Qeyd etdiyiniz üsul ilə eləmişdim. Düzdü sıralayır ama sadecə ilk hərflə görə. Normalda mysql özü order eləyəndə sözdə olan hərflərin levellara görə order edir. İlk hərf eynidirsə keçir 2 ci hərfləri müqayisə edir. Ama bu numunələrdə ilk hərfi eyni olan 2 ci hərfi deyək ki x olan digər 2 ci hərfi m olan sözdən sonra gələcək. Halbu ki əvvəl gəlməlidi. Başqa bir variant gəlib ağlıma ama test etməmişəm bilmirəm nə dərəcədə effektiv olar. Test edib nəticəni yazacam
İndi aydındır.
X hərfi ilə yanaşı yəqin ki problem Q hərfi ilə də olacaq.
Burada təqsir mysql charsetdə yox, bizim əlifbadadır. Ümumi latın ardıcıllıq prinsipinə riayət edilməyib deyə, xüsusi azeri charset olmadan q və x hərfləri həll olmaz.
Sizin hal üçün alternativ kimi iki həll demək olar.
1. mysql-də bir rəqəm sütunu yaradın, kod tərəfdə də hər kəsin adının baş hərfini ora yazmaq, əlifbamızdakı tutduğu mövqeyə uyğun Məsələn Əli - 7, Ayxan - 1, Bənövşə, 2 və.s.
Ondan sonra da orderby-ı həmin sütuna görə vermək.
2. Bir də mysql-in özü ilə daha sadə yolla həll etmək. FIELD() funksiyası ilə.
Məsələn,
[sql]
select substr(name,1,1) ilkherf, name
from ADLAR
having ilkherf in ('A', 'B', 'C', 'Ç')
order by FIELD(ilkherf, 'A', 'B', 'C', 'Ç');
[/sql]
Siz nümunədəki 'A', 'B', 'C', 'Ç' əvəzinə tam əlifbanı yazmalısınız təbii ki.
Belə olan halda mysql məcbur qalacaq ki sırf sizin custom sıralama ilə orderby eləsin.
Sample data ve query burda əlavə etmişem
həm tək hərfləri order verəndə düz çıxmır həmdə datanı.
Bəlkə output nümunə qoyasınız daha aydın olsun deyə.
Azərbaycan əlifbasının spesifikasını mysql bilmir deyə ola bilər belə kiçik fərq. Amma yenə də output sample görsəm daha çox demək olar.
Alınmadı ama. table create query aşağıdakı kimidir. select query də qeyd edirəm aşağıda.
ə ı ü ş ğ bu hərfləri düzgün sıralaylr ama hansl ki ingilis əlifbası ilə eyni olan lakin bizde orderi fərqli olan hərfləri ingilis əlifbasına görə sıralayır. Məsələn x h dan sonra gəlməlidi ama sonda y dən əvvəl gəlir
[code]
CREATE TABLE `references` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_520_ci NOT NULL,
`surname` varchar(191) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
`father_name` varchar(191) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
) ENGINE=InnoDB AUTO_INCREMENT=1057 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
[/code]
[code]
select * from `references` order by `name` collate utf8mb4_unicode_520_ci;
[/code]
Mysql version mysql Ver 8.0.19 for osx10.15 on x86_64
Yox query-də heç bir şey etmək lazım deyil. Adicə default orderby işləyər. Sadəcə mysqldə lazımi sütunu yaradarkən düzgün chatset seçmək bəs edər
Təşəkkürlər. Bunu order eləyəndə collate olaraq vermeəliyəm yoxsa table ları yaradanda charset olaraq da bunu verməliyəm?
Multibyte charsetlər var mysql-də.
Məs. istifadə elədiyim charset - utf8mb4_unicode_520_ci
MySQL əlverişlidir yoxsa PDO ?
Verilənlər bazası-Müxtəlif məhsullar üçün müxtəlif xüsusiyyətlər