SAS按组更新多个记录

时间:2017-03-16 16:36:55

标签: sql sas duplicates sql-update proc

我有一个主A和事务集B.我试图在A中记录B中的记录和变量C中的记录。

DATA TEST;
  UPDATE A B;
  BY C;
RUN;

问题是,我的主设备中有一些重复的记录,我仍然想要更新它们。但我得到的是警告

  

指定的BY组有多个记录

只有这些重复的第一条记录才会更新。 有什么方法可以告诉SAS更新所有这些内容吗? 或者还有其他完全不同的方式吗?

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:1)

如果您确实想要应用事务,请展开您的事务文件,以获得关键变量C,D的所有可能值,以获取它包含的C值。

proc sql ;
  create table transactions as 
    select a.D,b.*
    from A right join B
    on a.C = b.C
    order by b.C,a.D
  ;
quit;

然后进行更新。

data want ;
  update A transactions ;
  id c d;
run;

如果您尝试使用MERGE,那么当两个表中都存在额外变量时,您将遇到麻烦。 SAS只会为每个C值更改第一条记录的值。您可以通过重命名B数据集中的变量来编程。然后,您可以显式编码是否希望该操作像MERGE或UPDATE。因此,如果您的额外变量名为E,那么您可以这样编码:

data want;
  merge a b(in=inb rename=(e=new_e)) ;
  by c ;
  updated_e = coalesce(new_e,e);
  if inb then merged_e = new_e ;
  else merged_e = e;
run;

因此,如果您想要合并的效果(因此事务中E的缺失值会使其缺少结果),那么请使用MERGED_E中的公式。如果您想要更新效果,请使用UPDATED_E中的公式。如果你有多个额外的变量,那么也要重命名它们并添加额外的赋值语句来处理它们。

答案 1 :(得分:1)

如果在用于更新的ID变量上创建索引,则可以使用modify语句执行此操作。这应该比使用更新语句快得多,因为它避免了创建主表的临时副本 - 但是,如果数据步骤被中断,则存在数据损坏的风险。语法有点笨拙,但如果有必要,它可能是宏观的。

data master;
input ID1 ID2 VAR1 VAR2;
cards;
1 1 2 3
1 2 3 4
2 1 5 6
;
run;

data transaction;
input ID1 VAR1 VAR2;
cards;
1 7 8
;
run;

proc datasets lib =work nolist nodetails;
modify master;
index create ID1;
quit;

data master;
set transaction(rename = (VAR1 = t_VAR1 VAR2 = t_VAR2));
do until(eof);
    modify master key = ID1 end = eof;
    if _IORC_ then _ERROR_ = 0;
    else do;
        VAR1 = t_VAR1;
        VAR2 = t_VAR2;
        replace;
    end;
end;
drop t_VAR1 t_VAR2;
run;