Bug #25955 Subtracting two fields from two joined sub query does not produce correct result
Submitted: 30 Jan 2007 21:42 Modified: 31 Jan 2007 10:20
Reporter: [ name withheld ] Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: Data Types Severity:S3 (Non-critical)
Version:5.0.32 Enterprise OS:Linux (Linux)
Assigned to: CPU Architecture:Any

[30 Jan 2007 21:42] [ name withheld ]
Description:
Subtraction of fields from two joined subqueries does not produce desired result.  See example below.  When Negative results are expected they are returned UNSIGNED.   Same results using various clients.

How to repeat:
-- 
-- Table structure for table `Example`
-- 

CREATE TABLE `Example` (
  `id1` int(10) unsigned NOT NULL,
  `id2` int(10) unsigned NOT NULL,
  `value` int(10) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- 
-- Dumping data for table `Example`
-- 

INSERT INTO `Example` VALUES (1, 1, 75);
INSERT INTO `Example` VALUES (1, 2, 100);

------------------------------------------------
mysql> SELECT * FROM Example;
+-----+-----+-------+
| id1 | id2 | value |
+-----+-----+-------+
|   1 |   1 |    75 | 
|   1 |   2 |   100 | 
+-----+-----+-------+
2 rows in set (0.00 sec)

mysql> SELECT
    -> s1.value,
    -> s2.value,
    -> (s1.value - s2.value) as difference
    -> FROM
    -> (
    -> select id1, value
    -> FROM Example
    -> WHERE id2=1
    -> ) s1
    -> LEFT JOIN
    -> (
    -> select id1, value
    -> FROM Example
    -> WHERE id2=2
    -> ) s2
    -> USING (id1)
    -> ;
+-------+-------+----------------------+
| value | value | difference           |
+-------+-------+----------------------+
|    75 |   100 | 18446744073709551591 | 
+-------+-------+----------------------+
1 row in set (0.00 sec)

Suggested fix:
Workaround:

mysql> SELECT
    -> s1.value,
    -> s2.value,
    -> CAST(s1.value - s2.value AS SIGNED)
    -> FROM
    -> (
    -> select id1, value
    -> FROM Example
    -> WHERE id2=1
    -> ) s1
    -> LEFT JOIN
    -> (
    -> select id1, value
    -> FROM Example
    -> WHERE id2=2
    -> ) s2
    -> USING (id1)
    -> ;
+-------+-------+-------------------------------------+
| value | value | CAST(s1.value - s2.value AS SIGNED) |
+-------+-------+-------------------------------------+
|    75 |   100 |                                 -25 | 
+-------+-------+-------------------------------------+
1 row in set (0.00 sec)
[31 Jan 2007 10:20] Sveta Smirnova
Thank you for taking the time to write to us, but this is not a bug. Please double-check the documentation available at http://dev.mysql.com/doc/ and the instructions on
how to report a bug at http://bugs.mysql.com/how-to-report.php

Please read warning at http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html