MySQL 文档 says :
The DECIMAL and NUMERIC types store exact numeric data values. These types are used when it is important to preserve exact precision, for example with monetary data.
我对该列 decimal_column DECIMAL(31,30)
进行了测试。
insert into tests (decimal_column) values(1/3);
然后检查已存储的内容给出了这个
select * from tests ;
> result : 0.333333333000000000000000000000
然后用这个查询反转数学运算得到这个
select decimal_column*3 from test;
> result: 0.999999999000000000000000000000
我期望得到整数“1”,就像我们在计算器和 Excel 工作表中所做的那样!像这样
#calculator or excel sheet
>input: 1 / 3
>result: 0.3333333333333333333333333333333333
>input: * 3
>result: 1
1- 为什么 MySQL 没有存储 (1/3) 的精确二进制表示,因此我可以在我的计算中再次使用该结果,因为它们像计算器或 Excel 工作表一样在内存中.
2- 如何在 mysql 中存储 (1/3)
的结果,因为它们在计算期间在内存中,所以我可以检索准确的值并执行类似 3 * $storedValue
的操作,以得到 1 的整数,就像我们在计算器或 Excel 工作表中所做的那样。
最佳答案
问题不在存储中。在您的示例中,该值在存储到表中之前已损坏。
不幸的是,如果你写 1/3,将使用默认表示计算(并插入):
SELECT 1/3
0.333333333
如您所见,精度不够。
另一个问题是,当您向服务器发送常量(1 或 3)时,您需要使用库 或连接器,这可能需要自由与值(value)。例如,它可能认为“1”和“3”是整数,并且它们的结果将被视为整数。所以你得到“1/3 = 0”,但是“1./3 = 0.333333”,因为“1”中的点。使连接器意识到它需要使用其默认 float 。而且你只得到六个 3,因为连接器的“默认 float ”有 6 个数字。然后将其存储到数据库中,但为时已晚。您正在以高精度存储一个已被截断为低精度的值。
您可以尝试从一开始就强制转换常量。您可以使用 1 作为足够大的小数来代替“1”。我在这里使用您的 31,30,但请检查您是否不需要存储更大的数字。可能,“31,20”会更好。
mysql> SELECT 1/3 UNION SELECT CAST(1 AS DECIMAL(31,30))/CAST(3 AS DECIMAL(31,30));
+----------------------------------+
| 1/3 |
+----------------------------------+
| 0.333333333000000000000000000000 |
| 0.333333333333333333333333333333 |
+----------------------------------+
2 rows in set (0.00 sec)
虽然很别扭,但效果应该会更好。另外,我认为只需要在表达式中转换 一个 值;然后 MySQL 将根据需要升级所有涉及的数量。因此,将 CAST(0 AS DECIMAL(x,y)) 添加到求和中并将 CAST(1 AS DECIMAL(x,y)) 添加到乘法中可能就足够了。
mysql> SELECT 3*CAST(1 AS DECIMAL(31,30))/CAST(3 AS DECIMAL(31,30));
+-------------------------------------------------------+
| 3*CAST(1 AS DECIMAL(31,30))/CAST(3 AS DECIMAL(31,30)) |
+-------------------------------------------------------+
| 1.000000000000000000000000000000 |
+-------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT CAST(1 AS DECIMAL(31,30))*1/3;
+----------------------------------+
| CAST(1 AS DECIMAL(31,30))*1/3 |
+----------------------------------+
| 0.333333333333333333333333333333 |
+----------------------------------+
1 row in set (0.00 sec)
请注意,这不起作用,因为乘法具有更高的优先级:
mysql> SELECT CAST(0 AS DECIMAL(31,30))+1/3;
+----------------------------------+
| CAST(0 AS DECIMAL(31,30))+1/3 |
+----------------------------------+
| 0.333333333000000000000000000000 |
+----------------------------------+
1 row in set (0.00 sec)
关于mysql - 如何将十进制计算结果存储在mysql中并像在内存中一样将其检索回来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42833474/