Porovnanie v mysql

Programovacie jazyky, rady, poradňa...
t0m4s3
Admin
Admin
Používateľov profilový obrázok
Príspevky: 18096
Registrovaný: 14 jún 2004, 18:35
Bydlisko: Martin SR, Brno CZ
Kontaktovať používateľa:

Porovnanie v mysql

Príspevok od používateľa t0m4s3 »

- verzia mysql 5.0.41
- problem: Mam dvoch userov a hodnotu nejakeho parametru napriklad

Kód: Vybrať všetko

meno     cislo
User A : 123.28
User B : 96.78
mysql query je SELECT meno FROM blabla WHERE cislo > 96.78
z tohto mi vypadne jeden user. V poriadku. Ak dam query ale SELECT meno FROM blabla WHERE cislo > 123.28 nemalo by sa zobrazit nic, tzn. 0 riadkov. Avsak vyhodi mi to takisto prveho usera. Pokial dam iba > 123.29 tak uz to nehodi ziadneho.

Podobna situacia ked > nahradi >=. V prvom pripade to spravne vyhodi jedneho usera, v druhom pripade by malo zahrnut uz aj druheho, opat vsak vyhodi iba prveho.

Som z toho jelen. Nevie niekto kde robim chybu?
programator
Medium Star
Medium Star
Používateľov profilový obrázok
Príspevky: 475
Registrovaný: 18 apr 2005, 8:31
Bydlisko: Papua new Guinea
Kontaktovať používateľa:

Príspevok od používateľa programator »

Podla mojho nazoru tento problem spociva v nepresnosti v desatinnych radoch...
Ak by sme zobrali do porovnavania napr. premennu typu double, niekde na 15-16 des. mieste nastava nepresnost...
Zoberme napr. User A.
Cislo v pamati moze vyzerat priblizne takto : 123.2800000000000001
A tym padom pri query typu SELECT meno FROM blabla WHERE cislo > 123.28 bude neocakavany vysledok...
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

To je klasický problém so zaokrúhľovaním (teda presnejšie s tým, že keď zadáš číslo 123.28, tak môže byť najbližšie číslo, s ktorým vie pracovať CPU napr. 123.2799999).
Porovnávanie FLOAT sa robí tak, že si vyberieš nejakú požadovanú presnosť a potom použiješ niečo ako:

Kód: Vybrať všetko

SELECT meno FROM blabla WHERE ABS(cislo - 123.28) > 0.0001 AND cislo < 123.28
Možno by sa to dalo urobiť aj tak, že by si to "cislo" (po vynásobení nejakou konštantou) zmenil na INT (a až potom porovnával).

// chrono: programator ma predbehol (asi mu netrvalo odoslanie jedného príspevku pol hodinu) :)
t0m4s3
Admin
Admin
Používateľov profilový obrázok
Príspevky: 18096
Registrovaný: 14 jún 2004, 18:35
Bydlisko: Martin SR, Brno CZ
Kontaktovať používateľa:

Príspevok od používateľa t0m4s3 »

Tak asi problem nasmerujem inym smerom. Ako spocitat, kolko ludi je pred clovekom s cislom XYZ (ktory je v uvedenom tvare, s tromi desatinymi miestami)?
caesar1987
Addict
Addict
Používateľov profilový obrázok
Príspevky: 3001
Registrovaný: 02 okt 2005, 0:57
Bydlisko: Nové Zámky
Kontaktovať používateľa:

Príspevok od používateľa caesar1987 »

ukladaj tie cisla do databazy v tvare napr

82.09 -> 82090
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Vyskúšaj:

Kód: Vybrať všetko

SELECT COUNT(*) AS pocet FROM `float` WHERE CAST((f*1000) AS SIGNED) < 130.123*1000

Kód: Vybrať všetko

SELECT COUNT(*) as pocet FROM `float` WHERE ABS(f - 130.123) > 0.001 AND f < 130.123
// chrono: samozrejme v tom prvom má byť to posledné číslo tiež INT
t0m4s3
Admin
Admin
Používateľov profilový obrázok
Príspevky: 18096
Registrovaný: 14 jún 2004, 18:35
Bydlisko: Martin SR, Brno CZ
Kontaktovať používateľa:

Príspevok od používateľa t0m4s3 »

to "f" je co??
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Stĺpec s číslom (v tom tvojom príklade sa to volá cislo)
t0m4s3
Admin
Admin
Používateľov profilový obrázok
Príspevky: 18096
Registrovaný: 14 jún 2004, 18:35
Bydlisko: Martin SR, Brno CZ
Kontaktovať používateľa:

Príspevok od používateľa t0m4s3 »

Obe sql sa chovaju rovnako. Prvy aj druhy v poradi vypluju cislo 1 :-(
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Hmm. Testoval som to a fungovalo to normálne. Vyskúšam tam pridať viac čísel a otestujem to ešte raz.

// chrono: Takže pridal som viac čísel, a funguje to normálne (možno máme iné typy toho čísla)
Napísať odpoveď