mysql> select id, ymd, code, price,
-> case
-> when code like '%xua%' then round(price/100,2)
-> when code like '%jp%' then round(price/1000,3)
-> else round(price/100000,5)
-> end as t
-> from test ;
+------+------------+-------+--------+------------+
| id | ymd | code | price | t |
+------+------------+-------+--------+------------+
| 1 | 2019-01-01 | auus | 75125 | 0.75125 |
| 2 | 2019-01-02 | nzus | 68541 | 0.68541 |
| 3 | 2019-01-03 | xuaus | 131485 | 1314.85000 |
| 4 | 2019-01-04 | aujp | 77852 | 77.85200 |
| 5 | 2019-01-05 | usjp | 110852 | 110.85200 |
| 6 | 2019-01-06 | xuaus | 131091 | 1310.91000 |
+------+------------+-------+--------+------------+
6 rows in set (0.04 sec)
使用FORMAT而不是ROUND:
mysql> select id, ymd, code, price,
case when code like '%xua%' then format(price/100,2)
when code like '%jp%' then format(price/1000,3)
else format(price/100000,5) end as t from test;
+------+------------+-------+--------+----------+
| id | ymd | code | price | t |
+------+------------+-------+--------+----------+
| 1 | 2019-01-01 | auus | 75125 | 0.75125 |
| 2 | 2019-01-02 | nzus | 68541 | 0.68541 |
| 3 | 2019-01-03 | xuaus | 131485 | 1,314.85 |
| 4 | 2019-01-04 | aujp | 77852 | 77.852 |
| 5 | 2019-01-05 | usjp | 110852 | 110.852 |
| 6 | 2019-01-06 | xuaus | 131091 | 1,310.91 |
+------+------------+-------+--------+----------+
6 rows in set (0.00 sec)
mysql> select @@version;
+----------------------------------------+
| @@version |
+----------------------------------------+
| 10.3.11-MariaDB-1:10.3.11+maria~bionic |
+----------------------------------------+
1 row in set (0.00 sec)
请注意,它在适当时包含“千位分隔符”。请参阅FORMAT()的第3个参数或Locale设置以更改它。
我怀疑显示过程是以不同方式格式化输出。通过从ROUND切换到FORMAT,我设法让MariaDB的输出几乎与MySQL相同。剩下的差异是添加的逗号(“千位分隔符”),可能显示为“。”对于某些语言环境。
相比之下,对于MySQL 5.6.22:
+------+------------+-------+--------+---------+
| id | ymd | code | price | t |
+------+------------+-------+--------+---------+
| 1 | 2019-01-01 | auus | 75125 | 0.75125 |
| 2 | 2019-01-02 | nzus | 68541 | 0.68541 |
| 3 | 2019-01-03 | xuaus | 131485 | 1314.85 |
| 4 | 2019-01-04 | aujp | 77852 | 77.852 |
| 5 | 2019-01-05 | usjp | 110852 | 110.852 |
| 6 | 2019-01-06 | xuaus | 131091 | 1310.91 |
+------+------------+-------+--------+---------+
数值相同,但显示不同。差异似乎来自命令行工具mysql,而不是来自ROUND本身。请注意,t是右对齐的,暗示值被视为数字。
如果这足以冒犯别人,请向MariaDB提交错误报告。
77.75200000000001 - 这是使用DOUBLE而不是所有DECIMAL的一些中间计算的代表。 MySQL(和MariaDB)在猜测数字的前提方面做得相当不错。通常他们会做任何事情。
在DOUBLE,77.75200000000001并不完全等于DECIMAL 77.752,因为一个是二进制,一个是十进制。出于这个原因,我经常建议不要使用FLOAT或DOUBLE作为“钱”。
假设您的真正目标是将货币值表示为77.7520000000000000000000000...,那么就是'77 .752',并且假设您需要最多5个小数位来表示各种值,我建议您这样做:
t DECIMAL(m, 5)
其中m对于您最终可能具有的任何值都是适当大的数字。对于给出的数字,(9,5)就足够了,但我怀疑你应该做更多像DECIMAL(14,5),以允许10亿美元/欧元/日元/等。
我不知道的是在处理DOUBLE的地方。
最新的'建议'
将DECIMAL(14,5)用于系统中的所有货币值,而不是INT。
14,5让你获得高达十亿美元的资金;根据您的预期最大值需要更改。
忽略我对FORMAT()的评论;这似乎太混乱了。
摆脱CASE条款,至少为特定用法。
DECIMAL值中的大多数算术都是精确的,不会遇到77.75200000000001。如果它再次出现,请启动一个新的问题,并包括计算中涉及的所有步骤,数据类型等。
以上注释涉及存储和计算。要显示,请说明要求:
计划A:小数点后5位即可。
计划B:对于某些值,需要舍入到3或2位小数。
计划C:您有应用程序代码,而不是SQL,可以处理该问题。
计划D:......