0

我有一个销售税值,我需要将其平均分配到 3 个项目中。例如:$153.88/3 = 51.29333333333333

当四舍五入到小数点后 2 位以表示货币时,it = $51.29. 但是$51.29*3=$153.87,这比总税额少 1 美分。

是否有解决这些舍入误差的功能,以便各个值始终加起来?那么额外的 1 美分随机分配给 1/3 项?

select '1' as item_number, 153.88 as sales_tax, round(153.88 /3,2) as rounded
union all
select '2' as item_number, 153.88 as sales_tax, round(153.88 /3,2) as rounded
union all
select '3' as item_number, 153.88 as sales_tax, round(153.88 /3,2) as rounded
     
4

2 回答 2

0

考虑下面

select * except(pre_split, pos), 
  round(if(pos > round(100 * (sales_tax - sum(pre_split) over()), 2), 
    pre_split, pre_split + .01)
  , 2) final_split
from (
  select *, 
    round(sales_tax / count(1) over(), 2) pre_split,
    row_number() over(order by rand()) pos
  from `project.dataset.table`
)   

如果适用于您问题中的样本数据 - 输出是

在此处输入图像描述

下一次运行输出

在此处输入图像描述

下一次运行...

在此处输入图像描述

因此,正如您所看到的 - 额外的分是随机应用的 - 就像 rand() 函数运行的那样随机 :o))

此外,如果超过一美分 - 所有美分也将均匀随机应用

于 2021-02-06T01:41:05.790 回答
0

这是一个棘手的问题。使用floor(), ceil(), 或round()获得近似解非常简单。然后,您甚至可以将“额外”添加到其中一行。

然而,额外的可能超过 0.01,这开始看起来很尴尬。当您拥有三个项目时不会发生这种情况,但可能会发生更多项目。我更喜欢将这些均匀分布在行上。

所以,我推荐:

with t as (
      select '1' as item_number, 153.89 as sales_tax
      union all
      select '2' as item_number, 153.89 as sales_tax
      union all
      select '3' as item_number, 153.89 as sales_tax
      union all
      select '4' as item_number, 153.89 as sales_tax
      union all
      select '5' as item_number, 153.89 as sales_tax
      union all
      select '6' as item_number, 153.89 as sales_tax
      union all
      select '7' as item_number, 153.89 as sales_tax
)
select t.*,
       (floor(sales_tax * 100 / count(*) over ()) +
        (case when floor(sales_tax * 100 / count(*) over ()) * count(*) over () +
                   row_number() over ()  - 1 < sales_tax * 100
              then 1 else 0
         end)
       ) / 100.0
from t;

我已经包含了一个分布产生影响的示例。

于 2021-02-06T02:01:00.583 回答