【问题标题】:SAS Proc sql row numberSAS Proc sql 行号
【发布时间】:2015-01-15 15:40:20
【问题描述】:

如何获取proc sql中观察的行号,类似于proc sql中datastep的_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
    .
    .
    .

【问题讨论】:

    标签: sql sas proc-sql


    【解决方案1】:

    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;
    

    这几乎不会增加任何开销 - 几毫秒 - 并获得相同的结果,但可以确保您有正确的排序。这两个查询(this 和 shipt's)在我的机器上运行的时间几乎相同,完全在误差范围内(所有记录分别为 2.95 秒和 2.98 秒)。

    【讨论】:

    • 谢谢,我想这也是真的 - 但鉴于 support.sas.com/rnd/scalability/papers/SR-71.pdf(我知道是旧的)说数据步骤没有线程,使用 NOTHREAD 关闭线程具有相同的效果,假设效果传入datastep视图是使proc sql单线程吗?
    • 我不确定 SQL 是否真的是单线程的 - 即使它没有同时运行多个事物,它有时仍然不会按照您期望的顺序执行事物(尤其是 group by 和类似的)。单线程数据步高效;无论如何,单线程 SQL 不是。
    【解决方案2】:

    使用 monotonic() 函数。虽然在过去我读到这是一个未记录的函数(它确实没有出现在 sas 网站上,但至少有 one sas 'proceedings' document which makes use of it heavily

    例如:

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

    会实现你的目标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多