我正在使用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使用可以容纳我的总值的字段长度创建一个表?它们的数量在十亿 - 千亿之间,所以我认为这并不奇怪。我很想知道你们的想法。
答案 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能够处理如此大的数字。