Sql 将所有数字四舍五入,但保留总和

Sql 将所有数字四舍五入,但保留总和,sql,postgresql,Sql,Postgresql,假设我有以下4项记录: CASH ======== 1993.772 5015.572 996.884 1993.772 这些数字加起来等于10000.00。现在我想将所有这些数字四舍五入到小数点后两位,但将总和保持为10000.00 在上面的示例中,如果我删除最后一个数字,则数字的总和将是9999.99,而不是10000.00,但这样的总和仍然是10000.00: CASH ======== 1993.78 <- changed from 1993.

假设我有以下4项记录:

CASH    
========    
1993.772
5015.572
996.884
1993.772
这些数字加起来等于
10000.00
。现在我想将所有这些数字四舍五入到小数点后两位,但将总和保持为
10000.00

在上面的示例中,如果我删除最后一个数字,则数字的总和将是
9999.99
,而不是
10000.00
,但这样的总和仍然是
10000.00

CASH    
========    
1993.78   <- changed from 1993.77 to 1993.78
5015.57
996.88
1993.77
现金
========    

1993.78这是一个挑战。这里有一种方法:

select t.*,
       round(cash, 2),
       (case when row_number() over (order by cash desc) = 1
             then sum(cash) over () - sum(round(cash, 2)) over (order by cash rows between unbounded preceding and 1 preceding)
             else round(cash, 2)
        end)
from t;
他是一把小提琴

基本上,这会将所有值舍入到小数点后两位,最大值除外。对于这一个,它从总数中减去四舍五入值之和


注意:这会将额外值添加到最大值上。它可以对最小的值进行四舍五入,但我认为对最大值进行四舍五入更安全(对值进行较小的增量更改)。如果有其他列指定排序,则可以选择“第一”或“最后”列。

这是一个挑战。这里有一种方法:

select t.*,
       round(cash, 2),
       (case when row_number() over (order by cash desc) = 1
             then sum(cash) over () - sum(round(cash, 2)) over (order by cash rows between unbounded preceding and 1 preceding)
             else round(cash, 2)
        end)
from t;
他是一把小提琴

基本上,这会将所有值舍入到小数点后两位,最大值除外。对于这一个,它从总数中减去四舍五入值之和


注意:这会将额外值添加到最大值上。它可以对最小的值进行四舍五入,但我认为对最大值进行四舍五入更安全(对值进行较小的增量更改)。如果您有其他列来指定顺序,则可以选择“第一”或“最后”列。

将所有值汇总为一个和,并汇总到一个数组中,然后将数组展开回到各自的行中

选择
unnest(数组_agg(四舍五入(ct.cash,2)))作为现金,
四舍五入(总金额(现金),2)总计
现金流量表中的现金流量;
结果

  cash  |  total
--------+---------
1993.77 | 10000.00
5015.57 | 10000.00
996.88  | 10000.00
1993.77 | 10000.00

将所有值向上聚合为一个和,再聚合为一个数组,然后将数组展开回到各自的行中

选择
unnest(数组_agg(四舍五入(ct.cash,2)))作为现金,
四舍五入(总金额(现金),2)总计
现金流量表中的现金流量;
结果

  cash  |  total
--------+---------
1993.77 | 10000.00
5015.57 | 10000.00
996.88  | 10000.00
1993.77 | 10000.00

请向我们显示您的预期结果。@GMB更新了问题,请向我们显示您的预期结果。@GMB更新了我得到的最后几列的问题HM'null,9003.120,7009.350,5015.580`@Yar。我修正了逻辑并为最后一列添加了dbfiddle.hm,我得到的'null,9003.1207009.3505015.580`@Yar。我修正了逻辑并添加了一个dbfiddle。
cash
值的总和不是10000。这是在对预先舍入的数字求和时。出于好奇,你认为他们的总数是多少?这就是问题的关键所在。OP希望四舍五入的数字增加到10000,与预四舍五入的数字相同。只需查看最后的数字(7,7,8,7),您就可以立即看出结果不是以0结尾。
cash
值的总和不是10000。这是在对预四舍五入的数字求和时。出于好奇,你认为他们的总数是多少?这就是问题的关键所在。OP希望四舍五入的数字增加到10000,与预四舍五入的数字相同。只需查看最后的数字(7,7,8,7),您就可以立即判断结果不是以0结尾。