总和上的奇数行为(获取数字溢出)

时间:2013-07-25 19:13:48

标签: sas teradata

我正在使用SAS proc sql查询并发现了一些奇怪的东西。首先,我尝试了这个简单的查询:

proc sql;
  CREATE TABLE test AS 
    (SELECT
       YEAR(dt) AS yr,
       MONTH(dt) AS mo,
       SUM(val) AS total
     FROM
       mydb1234.myTable
     WHERE
       myDate BETWEEN x AND y
     GROUP BY
       yr, mo);
run;

当我运行此查询时,收到此错误:

ERROR: Teradata row not delivered (trget): Numeric overflow occurred during computation.

据我所知,当我的求和值太大而无法适应proc sql试图使用的数据类型时,会发生这种情况。

我决定将我的数字除以:

SUM(val/1000) AS total

但是,这会产生意想不到的后果。总和小于我在Excel中所做的手动总和。随着我向除数增加更多的数量级,总数会降低。我猜这是在消除它试图求和的较小值(例如10/1000 vs 108/10000等),它们永远不会达到总和,而是被读作零。

有没有办法强制这个proc sql使用可以容纳我的总值的字段长度创建一个表?它们的数量在十亿 - 千亿之间,所以我认为这并不奇怪。我很想知道你们的想法。

3 个答案:

答案 0 :(得分:5)

我怀疑发生的事情是查询通过隐式传递被推回到Teradata,而某些东西在Teradata中不起作用。您可能需要查询显式地将总和转换为除了它之外的其他内容。

要准确了解发生了什么,请使用OPTIONS SASTRACE;从文档中建议尝试

options sastrace=',,,d' sastraceloc=saslog nostsuffix;

虽然您可能需要选择一些选项。这将显示在Teradata中执行的确切查询。直接在Teradata中尝试相同的查询,看看是否可以防止它出现同样的问题。

一旦你想出来,你可以使用显式传递执行正确的查询;即

proc sql;
 connect to teradata [options, same as on the libname usually];
 create table mydata as select * from connection to teradata (
   ... actual teradata syntax ...
 );
quit;

答案 1 :(得分:1)

我将调查导致此问题的潜在问题,正如Joe之前指出的那样。但是,我找到了一个解决根本问题的快速解决方法。我在SUM

中使用了以下行
Round((SUM(myField))/1) format=13. 

答案 2 :(得分:0)

在这些类型的情况下,始终为Teradata表中的val列定义的数据类型导致了“数字溢出”问题。 (我假设val被定义为Integer类型,最多可以容纳+/- 21亿)

试试这个,

proc sql;
  CREATE TABLE test AS 
    (SELECT
       YEAR(dt) AS yr,
       MONTH(dt) AS mo,
       SUM(cast(val as dec(32,0))) AS total
     FROM
       mydb1234.myTable
     WHERE
       myDate BETWEEN x AND y
     GROUP BY
       yr, mo);
QUIT;

在上面的代码中,SUM(cast(val as dec(32,0)))首先将val列转换(正式)转换为可以容纳超过几十亿然后求和的数据类型。汇总列total将为dec(32,0),而且SAS能够处理如此大的数字。