【发布时间】:2020-12-27 04:59:23
【问题描述】:
数据
我有一个带有几列的 pandas DataFrame。其中一个是描述,存储为object,另一个是该描述的总量,存储为float64。类似这样:
id desc amount
12345 Item 1A 15.9
12345 Item 2N -3.9
12345 Item 1A 2.99
12345 Item 3 -5.15
12345 Item 3 -9.84
我使用 sqlalchemy 连接到数据库并使用 to_sql 导出 DataFrame:
con = sqlalchemy.create_engine("sqlite:///database.db")
df.to_sql(name = "table1", con = con, dtype = {"amount": sqlalchemy.Float()})
问题
在数据库中,我执行以下查询以获取支付给该 ID 的总金额:
SELECT id, SUM(amount) AS 'TOTAL PAID' FROM table1 GROUP BY ID;
数据库返回以下内容:
id TOTAL PAID
12345 -5.35510483179458e-10
正确的结果是:
id TOTAL PAID
12345 0
我已经检查过了,数据库中的 amount 列确实有正确的金额。我认为这可能与使用的数据类型有关,但我不确定。结果为 0 的所有 ID 都会发生。在 SUM 函数中具有不同结果的 ID 可以正常显示。由于该列是指钱,我只需要它存储小数点后两位数。
Here你可以找到显示问题的记录之一。
问题(TL;DR)
为什么 SQLite 显示一个指数而不是 0 作为聚合函数的结果?我怎样才能得到预期的结果?
编辑
当使用 SUM 函数时,它不仅仅显示那个指数数。它显示了不同 ID 的其他几个指数数字。也有一些ID总和为0,但不受影响。受影响的人和未受影响的人没有什么不同。
【问题讨论】:
-
这是因为你使用了花车。浮点数是近似值,而不是无限准确的奇迹。在网上搜索关于浮点数的近似值 (在所有使用浮点数的语言中都是如此,而不仅仅是 SQL),不要盲目地使用它们,对于货币值,您很可能应该使用小数,它们的可能值范围更有限,但它们是精确的,而不是近似值。 (为了清楚起见,你的结果是 -0.0000000005,这和该死的零一样好,除了使用浮点数引入的舍入误差。)
-
谢谢,@MatBailie。
-
简单地说,如果您想要精确的小数,请使用具有比例和精度的小数。如果您正在处理精度不如大小/性能重要的极大或极小数字,请使用浮点数。例如宇宙中有多少个原子;很好用的浮动。亚原子粒子之间的距离再次浮动。货币...使用小数。
-
代码工作正常并返回
0:dbfiddle.uk/… -
@forpas 在这里查看:dbfiddle.uk/…
标签: sql database pandas sqlite