proc sql sum并没有正确加起来

时间:2015-02-06 18:49:33

标签: sql sum sas

我的数据如下:

ID  Date1           Date2       Paid Amount
A               1/25/2012   -168.48
A               1/25/2012   -59.44
A               1/25/2012   -13.18
A               1/25/2012   -8.02
A               1/25/2012   8.02
A               1/25/2012   13.18
A               1/25/2012   59.44
A               1/25/2012   168.48
A   12/28/2011  1/25/2012   50.00
A   12/28/2011  1/25/2012   61.00


Proc sql;
Create table SUM as
Select id, date1, date2, sum(paid_amount) as paid_amount
From SUM_0
Group by id, date1, date2; 

我得到这样的东西:

ID Date1     Date2     paid_amount
A            1/25/2012 4.547474E-13
A 12/28/2011 1/25/2012 111.00

仅仅通过观察,很明显,空白日期1的paid_amount和2012年1月25日date2的总和应为0.出于某种原因,对于这个和其他类似的设置,我得到了各种与E-13值的总和

2 个答案:

答案 0 :(得分:3)

正如其他人所说,这是一个浮点问题。就像:

2/3 - 1/3 - 1/3 = 0

.6667 - .3333 - .3333 > 0

浮点数本质上是不精确的。

SAS中,您可以通过几种不同的方式处理此问题。最简单的两个:

  • 圆。 round(sum(...),0.01)会将其四舍五入到最接近的0.01,如果您愿意,可以舍入到最接近的0.000001;通常E-12是您开始看到浮点精度问题蔓延的地方,因此任何数量的零都会小于10左右。
  • 起毛。 Fuzz(...)会自动将接近整数的数字舍入到该整数。它没有围绕否则,只是接近真实整数的东西变成一个。

例如:

data test;
  input ID  $ Date1 :mmddyy10. Date2 :mmddyy10. Amount;
  datalines;
A      .         1/25/2012   -168.48
A      .         1/25/2012   -59.44
A      .         1/25/2012   -13.18
A      .         1/25/2012   -8.02
A      .         1/25/2012   8.02
A      .         1/25/2012   13.18
A      .         1/25/2012   59.44
A      .         1/25/2012   168.48
A   12/28/2011  1/25/2012   50.00
A   12/28/2011  1/25/2012   61.00
;;;;
run;

proc sql;
  select id, date1, date2, round(sum(amount),.01)
    from test
    group by 1,2,3;
quit;

答案 1 :(得分:0)

你应该在numeric(10, 2)内添加像sum()这样的强制转换。

sum(cast(paid_amount as decimal(10, 2)))