在PROC SQL中限制结果

时间:2012-07-31 18:40:30

标签: sas proc-sql

我正在尝试使用PROC SQL来查询具有数亿条记录的DB2表。在开发阶段,我想在这些记录的任意小的子集上运行我的查询(例如,1000)。我尝试使用INOBS来限制观察,但我相信这个参数只是限制SAS正在处理的记录数。我希望SAS只从数据库中获取任意数量的记录(然后处理所有这些记录)。

如果我自己编写SQL查询,我只需使用SELECT * FROM x FETCH FIRST 1000 ROWS ONLY ...(相当于SQL Server中的SELECT TOP 1000 * FROM x)。但PROC SQL似乎没有这样的选择。这需要很长时间才能获取记录。

问题:如何指示SAS任意限制记录数量从数据库返回

我读过PROC SQL使用ANSI SQL,它没有行限制关键字的任何规范。也许SAS不想将其SQL语法转换为特定于供应商的关键字?没有解决方法吗?

2 个答案:

答案 0 :(得分:28)

您是否尝试使用outobs中的proc sql选项?

例如,

proc sql outobs=10; create table test
    as
    select * from schema.HUGE_TABLE
    order by n;
quit;

或者,您可以使用SQL passthrough使用DB2语法(FETCH FIRST 10 ROWS ONLY)编写查询,但这需要您将所有数据存储在数据库中,至少是暂时的。

Passthrough看起来像这样:

proc sql;
    connect to db2 (user=&userid. password=&userpw.  database=MY_DB);

    create table test as
    select * from connection to db2 (
        select * from schema.HUGE_TABLE
        order by n
        FETCH FIRST 10 ROWS ONLY
    );
quit;

它需要更多语法,无法访问您的sas数据集,因此如果outobs适用于您,我建议您这样做。

答案 1 :(得分:7)

当SAS通过SAS语法与数据库通信时,部分查询可以转换为DBMS语言等效 - 这称为隐式传递。查询的其余部分由SAS“后处理”以产生最终结果。 根据SAS版本,DBMS供应商和DBMS版本,在某些情况下甚至是某些连接/ libname选项,SAS语法的不同部分可以在SAS和DBMS之间进行翻译/认为兼容,因此发送由DBMS而不是SAS执行。

使用SAS SQL选项 - INOBS和OUTOBS - 我通过不同版本的SAS在MS SQL和Oracle上做了很多工作,但是我还没有看到那些转换为TOP xxx类型的查询,所以这可能不是虽然支持但是当查询只触及DMBS数据(没有加入SAS数据等)时,应该是非常可行的。

所以我认为你留下了所谓的显式传递特定的SAS SQL语法来连接到数据库。这种类型的查询如下所示:

proc sql;
    connect to oracle as db1 (user=user1 pw=pasw1 path=DB1);
    create table test_table as
    select *
    from connection to db1
        ( /* here we're in oracle */
                  select * from test.table1 where rownum <20 
                )
    ;
    disconnect from db1;
quit;

在SAS 9.3中,语法可以简化 - 如果已经有LIBNAME连接,您可以重复使用它进行显式传递:

LIBNAME ORALIB ORACLE user=...;

PROC SQL;
connect to oracle using ORALIB;
create table work.test_table as
        select *
        from connection to ORALIB (
....

使用libname连接时,请确保在加载数据库时使用READBUFF(我通常设置约5000个左右)或INSERTBUFF选项(1000或更多)。

要查看是否发生了隐式传递,请设置sastrace选项:

option sastrace=',,,ds' sastraceloc=saslog nostsuffix;