避免每个产品单位 cost/profit 的舍入误差(来自批量购买)

Avoiding rounding errors for unit cost/profit per product (from bulk purchase)

对于我正在处理的应用程序,我需要计算每件产品的成本(我们批量购买)以及计算单位销售时的利润。

天真的方法是将成本直接存储为舍入结果。

例如,如果我以 1 美元的价格购买 3 件产品,并以每件 1 美元的价格出售它们(此处存储整数,因此数字以美分为单位)

100 / 3 = 33 => cost per unit

Database Columns: cost=33, price=100

现在如果我卖掉所有 3 个

3 * price = 300
total cost = 33 * 3 = 99
total profit = 300 - 99 = 201

这是错误的。你可以存储更高的精度,但如果你的产品价格很高,那么你仍然会出现同样的错误。

我能想到的另一种方法是存储批量购买价格和数量,这样您的利润计算总是准确的

Database columns: bulkprice=100, amount=3, price=100

3 * price = 300
total cost = (100/3) * 3 = 100
total profit = 300 - 100 = 100 -> correct!

但是,这种方法会给计算和我们的数据库查询带来额外的复杂性。

所以我的问题是:

谢谢!

使用正确的数据类型。 Integer(用于存储美分)不是正确的数据类型。并且 100/3 不等于 33。在记录成本或销售额时没有合理的理由使用除法。

使用 numericdecimal 数据类型。我将为此使用单个 table,因为看起来这就是你正在做的事情。(或正在考虑这样做。)

create table test (
  test_id integer primary key,
  trans_type char(1) not null 
    check(trans_type in ('b', 's')),
  cost numeric (14, 2) not null
    check (cost >= 0),
  qty integer not null 
    check (qty > 0)
);

-- Buy three things for a dollar.
insert into test values (1, 'b', 1.00, 3);

-- Sell each thing for a dollar.
insert into test values
(2, 's', 1.00, 1),
(3, 's', 1.00, 1),
(4, 's', 1.00, 1);

-- total cost
select sum(cost) as total_cost from test where trans_type = 'b';
total_cost
1.00
-- Sales and costs
select (select sum(cost) 
        from test 
        where trans_type = 's') as sales,
       (select sum(cost)
        from test
        where trans_type = 'b') as costs;
sales  costs
3.00   1.00
-- Total profit
select sales - costs as profit 
from (select (select sum(cost) 
              from test 
              where trans_type = 's') as sales,
              (select sum(cost)
              from test
              where trans_type = 'b') as costs) x;
profit
2.00

单位成本 是您可能会在报告中找到的内容,但不是您通常会在会计系统中找到的内容。你可以四舍五入。 (我没有。)

-- Unit cost
select test_id, cost/qty as unit_cost 
from test 
where trans_type = 'b';
test_id  unit_cost
1        0.33333333333333333333