tags:

views:

199

answers:

3

I have a Joomla system and I'm trying to change the search so that it correctly finds floating point values in the database.

So, I have a query that is built at runtime that looks something like this:

select 'column1'
from 'some_table'
where 'some_float_field' <=> '2.18'

This doesn't work, it never matches anything, even though I see records in the db with this value there.

So I tried to just do this instead:

select 'column1'
from 'some_table'
where 'some_float_field' <=> 2.18

No luck, so then I tried casting to a decimal (float doesn't work for some reason), so I tried this:

select 'column1'
from 'some_table'
where 'some_float_field' <=> CAST('2.18' AS DECIMAL(20, 2))

No dice...

Keep in mind that >= or <= returns the proper results, just <=> gives me issues.

How do I get equality to work here?

A: 

Consider this:

where abs(some_float_field) - 2.18 < 0.001
Seva Alekseyev
I understand the precision issue. In my case I don't care about precision past the 2nd decimal place. I just want to find anything that matches, I'm not looking to do any arithmetic.
Joseph
+1  A: 

Usually with these types of questions it's good to provide a small example to replicate your results.

Usually testing for exact float values is a bad idea since floating point precision isn't an exact science. It's much better to use some tolerance.

create table foo1 (col1 float);

insert into foo1 values (2.18);
select * from foo1 where abs(col1-2.18) <= 1e-6
dcp
Yeah in this case I'm actually trying to find a "weight" of something that the user is putting in, but they want to match exact numbers, so I have to meet the requirement.
Joseph
Is it a user requirement to have a float datatype in the table? Typically, when the users want exact fractional numbers (e. g. money), the decimal datatype is a much better choice. You'll be getting rounding issues for years to come. Think of it. And if it IS actually money, by any chance, waste no time and redesign for decimal RIGHT NOW. Trust me, I speak from experience here.
Seva Alekseyev
I do agree with Seva. The first thing I do before I start working on a new database is to run the following query and find how many float columns are used. SELECT DATA_TYPE, COUNT(*) AS mycount FROM information_schema.COLUMNS WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') GROUP BY DATA_TYPE ORDER BY mycount DESCIf I find that the number of double, float, bigint and blobs are too high then I assume there are going to be a lot of problems.If the number of decimal, date, datetime, tinyint is too small (or nill) then again there is a problem :)
shantanuo
Off-by-one-cent errors! On amounts that you cannot predict in advance! And you cannot catch them in testing! Accountants flipping out! And so on, and so forth.
Seva Alekseyev
@Seva you're totally right, but the problem is that i'm using a CMS, which generates these fields automatically, so i don't have any control over the schema unfortunately. It's very irritating to me that it doesn't support currency as a decimal
Joseph
@Seva I'm going to mark your answer as the accepted answer even though it doesn't work for what I was trying to do. It does definitely resolve the issue that I put forth in this question, though.
Joseph
The answer isn't mine. I just tried to scare you into a proper design :)
Seva Alekseyev
A: 

I found a way to check for what my users view as equality.

I had to convert the field to a character string and test the character sets, so this works fine for them:

select 'column1'
from 'some_table'
where CAST('some_float_field' AS CHAR) <=> '2.18'
Joseph