【问题标题】:Do it in proc sql在 proc sql 中执行
【发布时间】:2017-11-26 14:39:06
【问题描述】:

如何在 proc sql 中执行以下代码。 下面给出了两个 proc 语句和一个合并。

 proc sort data=new out=new1 nodupkey;
 by id;
 where roll=100;
 run;

 proc sort data new2 out =new4 nodupkey
 by id;
 where roll=100;
 run;

 data score;
 merge new4 (in=a) new1;
 by id;
 if a;
 run;

【问题讨论】:

    标签: sas


    【解决方案1】:

    您显示的合并相当于 SQL 左连接。您想要“new2”中的所有行,并忽略“new”中没有公共 id 的所有行。 id 的唯一性(每个预排序)进一步支持左连接等价。

    Proc SQL;
      select new.*, new2.* 
      from new2
      left join new on new.id = new2.id
      where roll=100
      order by id;
    quit;
    

    对于非典型数据的场景,merge中有many:many ids,left-join是不等价的。

    我确实省略了 NODUPKEY 等效项。假设选项 EQUALS 有效,组第一行的选择将是等效的。未记录的 MONOTONIC() 函数可用于将默认行顺序应用于子查询,然后可以在具有表达式的按组中使用。

    data LEFT;
      input id x1 x2 x3;
      datalines;
    1 1 1 1
    1 2 2 2 
    1 3 3 3
    2 1 1 1
    2 2 2 2
    3 3 3 3
    4 4 4 4
    5 5 5 5
    ;
    run;
    
    data RIGHT;
      input id  y1 y2 y3 x1;
    datalines;
    1 1 1 1 11
    2 1 1 1 22
    3 1 2 3 4
    3 2 3 4 5
    3 3 4 5 6
    4 1 1 1 44
    6 6 6 6 6
    ;
    run;
    
    proc sql; 
      select
        LEFT.id
      , coalesce(RIGHT.x1,LEFT.x1) as x1
      , LEFT.x2
      , LEFT.x3
      , RIGHT.y1
      , RIGHT.y2
      , RIGHT.y3
      from
      ( 
        select * from (select monotonic() as _seq_, * from LEFT) group by id having _seq_ = min(_seq_)
      ) 
      as LEFT
    
      left join
    
      (
        select * from (select monotonic() as _seq_, * from RIGHT) group by id having _seq_ = min(_seq_)
      )
      as RIGHT
    
      on
        LEFT.id = RIGHT.id
      ;
    

    我觉得有必要重申一下,SQL 左连接并不总是与合并相同,并且 SQL 没有在 DATA 步中隐含的公共变量“覆盖”。当 LEFT 和 RIGHT 在非关键变量上发生碰撞时,您需要在输出中选择将公共变量合并为一个新的同名变量。

    【讨论】:

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