2015-02-06 56 views
1

我有一個看起來像這樣的數據:PROC SQL和不加正確

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的付款金額1,但2012年1月25日的日期2應爲0.由於某些原因,對於此類和其他類似設置,我會得到各種E-13值。

+0

看起來像一個浮點問題。 「paid_amount」是貨幣還是小數列? – shawnt00 2015-02-06 18:53:22

+0

這是一個數字,沒有指定的格式或信息,長度爲8. – PinkyL 2015-02-06 18:55:00

+0

你輸出第二行應該是111,而不是110.00 ..你可以在這裏檢查,其工作正常http://sqlfiddle.com/#!3/8a397 /1引導我們知道,你的表格結構是什麼 – HaveNoDisplayName 2015-02-06 18:57:28

回答

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; 
+0

我的印象是,金額值是以浮點形式存儲的貨幣值。 'round()'將它們轉換爲新類型嗎?如果沒有,那麼我認爲有一些潛在的錯誤積累。雖然我承認這將需要很長時間的交易清單才能轉化爲便士,但這值得考慮嗎? – shawnt00 2015-02-09 18:21:12

+0

SAS沒有其他類型:只是浮點數(默認8字節,如果需要少3字節)和字符。問題是隻有兩個操作最終可能不會完全等於零,如果在代碼中使用'if x = 0'或類似的話,這是一個問題。 – Joe 2015-02-09 18:29:25

+0

我明白爲什麼四捨五入「修復」這個特殊的時候,總和應爲零。我只是試圖解決使用浮點數的小數類型的更廣泛的問題。 – shawnt00 2015-02-09 18:46:03

0

您應該在sum()內添加一個像numeric(10, 2)這樣的演員。

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

錯誤我很新的SQL,你能解釋/詳細說明嗎?謝謝。 – PinkyL 2015-02-06 19:35:15

+0

'PROC SQL'只是SAS中SQL的一個實現,並不支持'CAST'函數 – mjsqu 2015-02-08 21:59:11

+0

那麼必須有一些等價物轉換爲十進制/數字/貨幣類型。他們的關鍵是在總結之前做到這一點。 – shawnt00 2015-02-09 03:33:37