Proc SQL中`where ... in(...)`子句的最大数量或参数?

时间:2015-01-23 21:41:26

标签: sas proc-sql

假设我对一个表进行了子集化并在proc sql中对其进行了总结。代码使用where ... in子句和子查询来进行子集化。我知道有些SQL引擎会对where ... in子句的参数数量设置一些限制。 SAS对此有限制吗?这个问题适用于这样的程序:

proc sql;
    create table want as
    select
        ID,
        sum(var1) as var1,
        sum(var2) as var2,
        sum(var3) as var3
    from largetable
    where ID in (select ID from longlist)
    group by ID;
quit;

如果longlist返回10,000个ID,该怎么办?怎么样10,000,000?

2 个答案:

答案 0 :(得分:4)

正如Joe所说,longlist表中任何合理数量的行都应该没有问题。但是,尽管这可能是可读的,a join may perform better

您是否强烈希望以书面形式运行查询,而不是进行左连接,例如

proc sql;
    create table want as
    select
        b.ID,
        sum(b.var1) as var1,
        sum(b.var2) as var2,
        sum(b.var3) as var3
    from longlist a left join largetable b
     on a.ID = b.ID
     group by b.ID;
quit;

详细说明输入长列表作为文本 - 我不知道SAS中任何一个语句的长度有任何限制,但是单个代码行的长度有various limits,具体取决于在您的版本以及您如何提交它。我怀疑有可能在一条线上拆分一条长语句,每条线都接近最大允许长度。

答案 1 :(得分:4)

我不知道对此有任何明确的限制。 SAS的SQL解析器似乎经常将它们转换为JOIN,当它们没有在表中明确编码时;这意味着有一些限制,但不是特别小。

我相信总共有一个SQL语句的长度是有限制的,所以如果你试图在 text 中包含一个非常长的列表,你可能会遇到问题,但是在这个例子中上面我没有看到10,000,000个ID的问题。我刚刚在longlist表中测试了250,000,000个ID,而SAS没有问题:

data largetable;
  do id=1 to 1e8;
    if mod(id,7)=0 then output;
  end;
run;

data ids;
  do id = 1 to 1e9;
    if mod(id,4)=0 then output;
  end;
run;

proc sql _method;
    create table want as
    select
        ID
    from largetable
    where ID in (select ID from IDs)
    group by ID;
quit;

有趣的是,添加_method表示它不是作为连接执行此操作,而是作为子查询执行此操作。我不知道为什么,至少在这种情况下;我被告知的一切都说它应该隐含地将它转换为连接。