ugrás a tartalomhoz

Distinctre összevonja az ékezetes betűket a MySQL

tiku I tikaszvince · 2005. Aug. 5. (P), 13.22
Sziasztok!
Van ez a lekérdezés:

SELECT DISTINCT LEFT(nev, 1) AS betu FROM olvaso ORDER BY betu
A probléma a következő:
Distinct nélkül gyönyörűen megjelennek a nevek első betűi (az összes magyar ékezetes betűket is beleértve). De ha a DISTINCT-et beleteszem, akkor az A-Á, E-É, I-I, O-Ó-Ö-Ő, U-Ú-Ü-Ű, betűket összevonja. Ha jól értelmezem a jeleket, akkor a párosokból/négyesekből az az első betű reprezentálja a többit, ami először bekerült a táblába.

De nekem arr alenne szükségem, hogy mindegyik betű szerepljen az eredményben és csak egyszer.

WinXP, MySQL 4.1.13-nt,
PHPMyAdmin szerint az egybevetés: utf8_unicode_ci, Charset:UTF8, Collation: utf8_unicode_ci

Thx
TikuVoltam
 
1

pont most volt ez

Hojtsy Gábor · 2005. Aug. 5. (P), 16.05
2

tényleg :)

tiku I tikaszvince · 2005. Aug. 5. (P), 17.25
Tényleg, hasonló a probléma, de ha megnézed én kérdeztem előbb :)

Lényeg a lényeg: átállítottam az oszlopot VARBINARY-ra meg is olddott a probléa. már nem vonja össze az ékezetes betűket.
DE mint fentebb is látható nekem az összes olyan betűre van szükségem, amivel kezdődik név, (ebből a listából generálom a linkeket, amivel a teljes listát lehet szűkíteni). Ha LEFT(nev, 1) van a lekérdezésben, akkor az ékezetes betűk mégis összevonódnak, de már 1 karakterré.

Nem mernék rá megesküdni, de arra gondolok, hogy 2 byte-on tárolódnak ezek a betűk, és ezekből is csak 1 byte-ot vesz figyelembe (Ha hülyeség akkor javítsatok ki). Azért gondolom ezt, mert, ha azt mondom, hogy LEFT(nev, 2), akkor már prímán megjelennek azok a fránya magánhangzók (1 betű), de az összes többi rekordból 2 betű. A poén, ahol a név második betűje ilyen "furcsa" magánhangzó, ott megint csak a furcsa karakter jelenik meg


Ezt valahogy ki lehet küszöbölni?

TikuVoltam
Ma is holnap fekszünk le, mint tegnap
3

furcsa karakterek

Hojtsy Gábor · 2005. Aug. 5. (P), 17.38
Valóban te kérdeztél előbb (néhány perccel), de a másikra válaszoltam előbb, azért linkeltem be azt :)

Ami a furcsa karaktereket illeti, az UTF8 két bájton ábrázolja a magyar ékezetes karaktereket, és ezeknek az első bájtja minden magyar karakterre ugyanaz. Úgy tűnik, hogy a LEFT() mégsem karakterekben számol, hanem bájtokban, vagy a charset nem UTF8-ra van állítva, csak annak tűnik (mondjuk tábla szinten más). Ha egyik sem, akkor dokumentáció alapján ez MySQL bugnak tűnik, és lehet hogy egy másik függvény használata segíthet (substring lekérdezés mondjuk).
4

úgy tünik bug

tiku I tikaszvince · 2005. Aug. 5. (P), 18.36
Megnéztem. SUBSTRING-el is ugyanaz az eredmény. ez a kód

<?php echo substr("ő"); ?>
is 2-t ír ki.
Lehetne azt is, hogy a PHP-ba bedrótozom, a teljes ABC-t, de ezt nem szeretném. Az lenne az igazi, ha azok a betűk, amelyel nincsen név, nem is jelennének meg.
Hogy lehetne ezt hatékonyan és elegánsan megoldani?

TikuVoltam
Ma is holnap fekszünk le, mint tegnap
5

ne keverjük a PHP-t a MySQL-lel

Hojtsy Gábor · 2005. Aug. 5. (P), 20.43
A PHP-vel ellentétben a MySQL-nek állítólag jól kell tudnia az utf8-at, a PHP nem tudja, ez nem meglepetés... Namost MySQL-ben mondom, hogy ha tényleg utf8-as charset meg collation van beállítva, akkor jó kellene legyen a substring. Én kipóbálnám, hogy egy literálisan megadott karaktersorozatra, amit utf8-ba kényszerítesz, mit ad vissza a left() meg a substring().
7

Megoldás (?)

tiku I tikaszvince · 2005. Aug. 6. (Szo), 09.49
Így utólag visszaolvasva, nem egyértelmű, hogy miért kevertem bele a PHP-t. Mea Culpa. Az volt az ötlet (amit ezek szereint, csak akartam leírni), hogy lekérek két karaktert (LEFT(nev, 2)), és a PHP-re bízom a válogatást.
Mielőtt ezt megcsináltam volna ellenőrizni akartam, hogy működik-e. Ez volt az előző magyarázata :)

A pontosítás kedvéért. Tényleg minden utf8-ra van állítva. A telepítéskor is utf8-at adtam meg defaultnak, a tábla létrehozásakor is minden utf8 volt.

Reggel, frissen (igaz még kávé nem volt) kipróbáltam a javaslatokat, és láss csodát, ez működik:

SELECT DISTINCT LEFT((nev COLLATE utf8_bin), 1) AS betu
FROM olvaso
ORDER BY betu
Csak az összes ékezetes magánhangzót a lista végére dobja. De ha nev szerint rendezem, akkor megint előjön az a probléma, hogy kb jó helyen jelennek meg (pl: oóöő, az n után, és a p előtt), de olyan sorrendben, ahogy a táblába bekerültek. (pl.: Ádám, előrébb van a táblában, mint Asztalos, így a kapott ABC-m így kezdődik Á,A,B).
Rá lehet venni valahogy a MySQL-t, hogy a magyar ABC szerint végezze a rendezést?

TikuVoltam
Ma is holnap fekszünk le, mint tegnap
6

collate utf8_bin

Balogh Tibor · 2005. Aug. 6. (Szo), 03.10
Talán próbáld meg így megadni a mezőt:
mezőnév varchar(x) binary
vagy a tábla collate tulajdonságát állítsd utf8_bin-re.

Ellenben, ha a mezőnek varbinary tipust adsz meg, az lehet, hogy már bináris formában tárolja az adatokat és nem utf kódolással, akkor is ha a tábla beállítása utf8.