views:

91

answers:

2

If a price in a row is 38.03, then the following search restrictions should all return the row containg the result.

WHERE price >= '38.02' AND price <= '38.03' (This works)

WHERE price >= '20' AND price <= '100' (This works)

WHERE price >= '38.03' AND price <= '38.03' (This doesn't work)

WHERE price >= '38.03' AND price <= '100' (This doesn't work)

WHERE price >= '38.03' (This doesn't work)

WHERE price <= '38.03' (This works)

The price is stored as a float in the DB.

So basically, <= is working whereas >= is not. Is there a reason why that could be?

A: 

When you use quotes (') your variables will be treated as strings. I think thats your problem.

Try: WHERE price >= 38.03 AND price <= 38.03

Johan
Try it yourself and you will notice that there is no difference. :)
Pekka
Given query above equals to WHERE price = 38.03
jancrot
mysql> SELECT 38.03 <= 38.03;result: 1mysql> SELECT 38.03 < 38.03;result: 0
Johan
@Johan: likewise, mysql> SELECT 38.03 <= '38.03'; result: 1 mysql> SELECT 38.03 < '38.03'; result: 0
BoltClock
+7  A: 

keep in mind that float is a flawed data type when it comes to precision. If you represent 12 as float, you will get 11.99999999999998 or something.

'38.03' can be converted to decimal, or other data type that is more precise (depending on RDBMS, I am being general here), and it will differ from the float value.

float is 32 bit, low precision. Double works a lot better, being 64 bit data type. Decimal data type in some systems are 128 bit numeric data types for storing very precise numeric values, and is usually used for denominating money.

And, skip the habit of comparing using the = operator, of float values. Floats are used for approximate and fast calculations, and only comparison with a range is acceptable for checking the value of a float. That's valid for basically every single system.

Alexander
+1 Yeah, just use `DECIMAL` instead. MySQL is pretty good with those.
BoltClock
Even 128 bits won't help you express 0.1 exactly. Money is best represented as whole and fractional parts as integers.
duffymo
@duffymo, you are talking about a fixed point decimal. There are 2 types of decimal, and some RDBMS have the `money` data type, which is a fixed point decimal with 2-4 decimal places.
Alexander
That of course, makes perfect sense now that you mention it. Why was I storing currency as a float and not a decimal? Sheer ignorance.
bcmcfc
Thanks for the correction, Alexander. I'll have to look into it, because my concern about rounding is true for all binary representations of floating point numbers. I'd still rather have the two integers for whole and fractional parts to ensure that rounding was done properly. Banks tend to care a great deal about those kinds of things.
duffymo
@duffymo, if I understand it correctly, fixed point decimals are exactly what you are saying - 2 integers. But look into it still, banks are something I haven't worked with yet, I only make statistics :).
Alexander