MySQL SUM 不是 return 正确的值,它会删除小数位。如何防止这种情况?
MySQL SUM do not return proper value, it removes decimal places. How to prevent this?
这对我来说很奇怪,我生平第一次见到。我不知道这是正确的行为还是出了什么问题。希望有高手赐教
这是我的简单 SQL Fiddle: http://sqlfiddle.com/#!8/ba125/4
我想做的很简单。我想为能源集团总结所有的钱。所以有 table 列称为 group。毫不奇怪,它包含公司所属的组的名称。其中,有一个名为 "energy" 的组。还有一列,称为 "money"。它包含每家公司每年赚取的金额(利润)。我需要对属于 "energy" 组的公司的所有利润(金钱)求和。听起来很简单,但我有一个问题。在 money table 中,money 以“1.234.567”这种格式存储为 varchar,这意味着这家公司的利润为 100 万 234,000...我对使用这种格式无罪,我正在努力系统在我开始工作之前很久就已经完成了。但是我的问题在哪里?好吧,如果你看一下 fiddle,我正在执行一个简单的查询,即能源组的选择资金:
select money from finance where group = "energy"
它很好地显示了每家公司赚了多少钱。但是如果我执行这个查询:
select sum(money) as total from finance where group = "energy"
我得到 99.317 的奇怪结果,我希望得到 18.103.571。这到底是怎么回事?我有希望得到正确的结果吗?谢谢
您必须删除 money
列中的所有点。
REPLACE
功能将解决您的问题。但这仍然不是优雅的解决方案。
SELECT SUM(REPLACE(money,'.','')) AS `money_sum` FROM finance WHERE `group` = "energy"
也许你会想到最优雅的解决方案? (例如没有点的格式)。
您的问题是您将整数值存储为 varchar
。当您像许多国家和地区一样开始使用小数作为千位分隔符时,这个问题会变得更加复杂,因为 MySQL 在自动将 varchar 转换为浮点数时会做出一些假设。
- 将数字存储为 INT。
- 去掉输入中的千位分隔符。规范化它。仅将数据存储为 INT,不带任何小数点或逗号。这将保证正确的算术运算。
事后格式化您的千位分隔符:
select REPLACE(REPLACE(REPLACE(FORMAT(SUM(MONEY),0), ',', '~'), '.', ','),'~', '.') AS format from finance where `group` = "energy"
不要将数字存储为 varchar(n)
。不要将数字作为字符串插入。
如果您的数字永远是整数,请使用 integer
。为了钱,你应该通常使用decimal
。使用适合您的货币的小数位数。对我来说,那是 2.
CREATE TABLE IF NOT EXISTS `finance` (
`id` mediumint(10) NOT NULL AUTO_INCREMENT,
`group` varchar(10) NOT NULL,
`money` decimal(14,2) NOT NULL,
primary key (`id`)
);
INSERT INTO `finance` (`group`, `money`) VALUES
('energy', 3543),
('other', 19881),
('other', 13536),
('other', 20),
('energy', 3607942),
('energy', 66768),
('energy', 10985),
('other', 2150),
('energy', 14414333);
select sum(money)
from finance
where `group` = 'energy'; -- 18103571.00
这对我来说很奇怪,我生平第一次见到。我不知道这是正确的行为还是出了什么问题。希望有高手赐教
这是我的简单 SQL Fiddle: http://sqlfiddle.com/#!8/ba125/4
我想做的很简单。我想为能源集团总结所有的钱。所以有 table 列称为 group。毫不奇怪,它包含公司所属的组的名称。其中,有一个名为 "energy" 的组。还有一列,称为 "money"。它包含每家公司每年赚取的金额(利润)。我需要对属于 "energy" 组的公司的所有利润(金钱)求和。听起来很简单,但我有一个问题。在 money table 中,money 以“1.234.567”这种格式存储为 varchar,这意味着这家公司的利润为 100 万 234,000...我对使用这种格式无罪,我正在努力系统在我开始工作之前很久就已经完成了。但是我的问题在哪里?好吧,如果你看一下 fiddle,我正在执行一个简单的查询,即能源组的选择资金:
select money from finance where group = "energy"
它很好地显示了每家公司赚了多少钱。但是如果我执行这个查询:
select sum(money) as total from finance where group = "energy"
我得到 99.317 的奇怪结果,我希望得到 18.103.571。这到底是怎么回事?我有希望得到正确的结果吗?谢谢
您必须删除 money
列中的所有点。
REPLACE
功能将解决您的问题。但这仍然不是优雅的解决方案。
SELECT SUM(REPLACE(money,'.','')) AS `money_sum` FROM finance WHERE `group` = "energy"
也许你会想到最优雅的解决方案? (例如没有点的格式)。
您的问题是您将整数值存储为 varchar
。当您像许多国家和地区一样开始使用小数作为千位分隔符时,这个问题会变得更加复杂,因为 MySQL 在自动将 varchar 转换为浮点数时会做出一些假设。
- 将数字存储为 INT。
- 去掉输入中的千位分隔符。规范化它。仅将数据存储为 INT,不带任何小数点或逗号。这将保证正确的算术运算。
事后格式化您的千位分隔符:
select REPLACE(REPLACE(REPLACE(FORMAT(SUM(MONEY),0), ',', '~'), '.', ','),'~', '.') AS format from finance where `group` = "energy"
不要将数字存储为 varchar(n)
。不要将数字作为字符串插入。
如果您的数字永远是整数,请使用 integer
。为了钱,你应该通常使用decimal
。使用适合您的货币的小数位数。对我来说,那是 2.
CREATE TABLE IF NOT EXISTS `finance` (
`id` mediumint(10) NOT NULL AUTO_INCREMENT,
`group` varchar(10) NOT NULL,
`money` decimal(14,2) NOT NULL,
primary key (`id`)
);
INSERT INTO `finance` (`group`, `money`) VALUES
('energy', 3543),
('other', 19881),
('other', 13536),
('other', 20),
('energy', 3607942),
('energy', 66768),
('energy', 10985),
('other', 2150),
('energy', 14414333);
select sum(money)
from finance
where `group` = 'energy'; -- 18103571.00