简体   繁体   中英

Using 'Greater than' operator with a negative number

I need to run several queries against columns containing both positive and negative numbers and return all rows that are either < or > than a selected value, however it's not returning the expected results when I use a 'Greater than' operator if the selected value is a negative number.

Please note that when the selected value is a negative number it should be returning both positive and negative numbers, and it seems to be excluding the negative numbers from the results.

SELECT T3.*    
FROM Rules T3
WHERE T3.Width > '-.80';

The values contained in T3.Width are:

0.90,(0.70),(0.70),(0.70),(0.70),(1.00),(1.00),(1.00),(1.00),(0.90),(0.55),(0.50)

Therefore the result should be:

0.90,(0.70),(0.70),(0.70),(0.70),(0.55),(0.50)

However the result being returned is:

0.90

The easiest solution is of course to use a DECIMAL() or FLOAT column in the table.

Since you are working with VARCHAR() types and prefer to continue working with VARCHAR , the RDBMS is not correctly treating () enclosed values as negatives, and instead attempting to cast the strings to an integer (which results in zero, and an incorrect comparison).

Working around the () enclosed negatives:

Using the () -enclosed negative values, you can REPLACE() the opening ( with a - and REPLACE() the closing ) with nothing, resulting in a value like -0.70 , but it is still a string to MySQL. You must then CAST it to a decimal value for the < > comparison.

SELECT Width
FROM T3
WHERE
  /* Replace the ( to -, and the ) with nothing
   * then cast it to a decimal value
   */ 
  CAST(REPLACE(REPLACE(Width, '(', '-'), ')', '') AS DECIMAL(10,2)) > '-0.8'

Example in action

Working with regular negative values in a VARCHAR column

If you change them to regular negative numbers but retain the VARCHAR type, you don't need all the nested REPLACE() but you will still need to cast it to a DECIMAL(10,2) .

SELECT Width
FROM T3
WHERE 
  CAST(Width AS DECIMAL(10,2)) > '-0.8'

Example 2:

your forcing a text comparison

SELECT T3.*    
FROM Rules T3
WHERE T3.Width > -.80;

uses a numerical comparison, The differnce being '-.80' vs -.80 is just the quotes.

When you compare by numerical value the query will return the expected results

if you HAVE to use quotes, use CAST('-.80' AS DECIMAL(12,2))

This gives 2 decimal places and 10 digits, Should be enough for most casts, though adjust if needed

If both arguments in a comparison operation are strings, they are compared as strings.

http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM