SAS Proc SQL行号

5

我该如何在proc sql中获取观测值的行数,类似于datastep中proc sql的_N_变量?

例如:

proc sql outobs=5;
    select case mod(<something>, 2)
    when 0 then "EVEN"
    else "ODD" 
    end
    from maps.africa
end;

希望:

Row
----------
    1 odd
    2 even
    3 odd
    .
    .
    .
2个回答

7
Monotonic()函数确实存在,在某些情况下可能有帮助,但它并不等同于行号,并且在使用时可能存在危险。特别是考虑到SQL是一种高度优化的语言,会将查询拆分成多个线程-在这种情况下,monotonic()无法实现您想要的功能。它尤其在不同的数据集、不同的SAS安装甚至不同的日期上表现可能不同。
安全的做法是创建一个view,并将_n_复制到一个永久变量中。
data africa_v/view=africa_v;
  set maps.africa;
  rownum=_n_;
run;

proc sql;
  select case mod(rownum, 2)
    when 0 then "EVEN"
    else "ODD" 
    end
    from africa_v;
quit;

这几乎不会增加任何负担 - 只需几毫秒 - 即可实现相同的结果,但可以确信您有正确的顺序。这两个查询(此查询和shipt的查询)在我的计算机上运行时间几乎相同,误差范围内(所有记录的2.95秒与2.98秒)。

谢谢,我猜这也是正确的 - 但是考虑到 https://support.sas.com/rnd/scalability/papers/SR-71.pdf(我意识到这是旧的)说数据步骤没有线程,使用 NOTHREAD 关闭线程是否会产生相同的效果,假设传递数据步骤视图的效果是使 proc sql 单线程运行? - undershock
我不确定 SQL 是否真正是单线程的 - 即使它没有同时运行多个任务,有时仍然不按照你期望的顺序执行事务(特别是在 group by 和类似情况下)。单线程数据步骤是高效的;无论如何,单线程 SQL 都不是高效的。 - Joe

2
使用monotonic()函数。虽然过去我曾读到这是一个未记录的函数(确实在SAS网站上没有出现过),但至少有一份SAS“会议文献”文件大量使用它。
例如:
proc sql outobs=5;
    select case mod(monotonic(), 2)
    when 0 then "EVEN"
    else "ODD" 
    end
    from maps.africa;
quit;

将实现您的目标。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接