此查询应返回 0.00,但返回 1.7763568394002505e-15:
SELECT st.id
, Sum(
CASE sa.Type
WHEN 4 THEN sa.quantity * (st.price - st.commission)
WHEN 5 THEN -sa.quantity * (st.price - st.commission)
ELSE 0.0 END
) Sales
FROM sales sa
JOIN stock st
ON sa.stockid = st.id
WHERE st.id = 1
GROUP BY st.id
http://sqlfiddle.com/#!5/cccd8/3
这看起来像是一个经典的浮点计算问题,但我该如何解决它? 我尝试过将各个列转换为 REAL,但没有什么区别。
您可以使用此查询模拟结果:
SELECT 26.3 - 10.52 - 15.78 AS Result
最佳答案
SQLite 的 REAL 不适合货币。 SQlite 不支持 SQL 小数或 SQL 数值数据类型,因此最好的选择是使用整数,并将值存储为分。
CREATE TABLE stock (
id INTEGER,
-- Store price and commission as integers, implying that price is in cents,
-- ($3.20 is stored as 320) and commission is a two-digit percentage (0.57%
-- is stored as 57). This is how scaled integers work in general.
price integer,
commission integer,
PRIMARY KEY(id)
);
CREATE TABLE sales (
id INTEGER,
stockid INTEGER,
type INTEGER,
quantity INTEGER,
PRIMARY KEY(id)
);
insert into stock values (1, 320, 57);
insert into sales values (1, 1, 4, 10);
insert into sales values (2, 1, 5, 4);
insert into sales values (3, 1, 5, 6);
来自 SQLfiddle 的此查询正确返回 0。
SELECT st.id
, Sum(
CASE sa.Type
WHEN 4 THEN sa.Quantity * (st.price - st.commission)
WHEN 5 THEN -sa.Quantity * (st.price - st.commission)
ELSE 0.0 END
) Sales
FROM sales sa
JOIN stock st
ON sa.stockid = st.id
WHERE st.id = 1
GROUP BY st.id;
id Sales ---------- ---------- 1 0
转换为更合适的数据类型(不是为 REAL)将隐藏一些问题——甚至可能是特定应用程序中的大多数问题,甚至所有问题。但转换并不能解决这些问题,因为存储的值可能与您真正想要的值不同。
关于SQLite浮点问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29800937/