我有这个奇怪的问题。我有一个包含2个数字的表,但是简单的计算会导致精度错误:
mysql> create table tblX as select '2.7' as H, '2100' as H2;
Query OK, 1 row affected (0.32 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select *, h-h2/1000 from tblX;
+-----+------+--------------------+
| H | H2 | h-h2/1000 |
+-----+------+--------------------+
| 2.7 | 2100 | 0.6000000000000001 |
+-----+------+--------------------+
1 row in set (0.00 sec)
此示例重现了我在设置中遇到的问题,其中以某些字段必须为varchars的方式提取公式,字段及其值的方式,而其他字段则用于上述计算。因此公式无法更改。另一个示例可能是一个公式,例如:if(code='c' and h-h2/1000>0.6,h,0)
字段是通过透视操作创建的。
我的假设是,将varchar隐式转换为十进制会导致此问题。我的问题是:是否有任何服务器设置可以更改此隐式转换。还是对此有其他解决方案。
编辑: 如果我这样修改列:
alter table tblX MODIFY column h decimal(20,4), MODIFY h2 decimal(20,4);
结果将是正确的。但是我不知道这些列的名称,因为它们是在临时表中动态创建的。如果可以创建一个脚本来修改仅包含数字值的所有列,那就太好了。
答案 0 :(得分:0)
我不知道任何服务器设置。但是您也可以在sql中进行显式转换。 尝试这样的事情:
select *, CAST(h-h2/1000 AS DECIMAL(10,2)) from tblX;
请参阅MySQL文档。 https://dev.mysql.com/doc/refman/5.5/en/fixed-point-types.html
答案 1 :(得分:0)
问题是,公式中的varchar显然隐式转换为浮点数而不是小数。在这种情况下,不能更改公式。但是修改列数据类型是一种选择。
解决方案是创建一个存储过程,该存储过程循环遍历相关列并将其修改为十进制数据类型。
包含错误数据类型的表称为tmp。
我制作了一个名为tmpPar的临时表,其中包含所有参与公式的列名称作为数值。然后,我设置一个游标并遍历所有这些列。光标循环如下所示:
DECLARE a varchar(255);
DECLARE cur1 CURSOR FOR SELECT CName FROM tmpPar;
...
Open cur1;
simple_loop: LOOP
fetch cur1 into a;
IF no_more_rows=1 THEN
LEAVE simple_loop;
END IF;
set @sql = null;
set @sql = concat('alter table tmp MODIFY column ' , a , ' decimal(20,4)');
PREPARE stmt FROM @sql;
EXECUTE stmt;
END LOOP simple_loop;
Close cur1;