1

假设我正在对一个表进行子集化并在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 怎么样?

4

2 回答 2

4

正如乔所说,表中任何合理数量的行都应该没有问题longlist。但是,尽管这可能是可读的,但连接可能会执行得更好

您是否强烈倾向于按书面形式运行查询而不是进行左连接,例如

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 中任何一条语句的长度有任何限制,但对各个代码行的长度有各种限制,具体取决于您的版本和您的方式'正在提交它。我怀疑可以将长语句拆分为几行,每行都接近最大允许长度。

于 2015-01-23T22:33:26.483 回答
4

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

我确实相信 SQL 语句的总长度是有限制的,所以如果你试图在文本中包含一个非常长的列表,你可能会遇到问题,但在上面的示例中,我没有看到 10,000,000 的问题身份证。我刚刚用 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 表示它不是将其作为连接,而是作为子查询。我不确定为什么,至少在这种情况下;我被告知的所有内容都表明它应该将其隐式转换为连接。

于 2015-01-23T22:33:57.923 回答