更新数据步骤中的语句

时间:2015-08-05 07:58:21

标签: sas datastep

在数据库中,我们有电子邮件地址数据集,如下所示。请注意,id 1003有两个观察结果

data Email;
    input id$ email $20.;
    datalines;
1001 1001@gmail.com
1002 1002@gmail.com
1003 1003@gmail.com
1003 2003@gmail.com
;
run;

我们收到用户更改电子邮件地址的请求,如下所示

data amendEmail;
    input id$ email $20.;
    datalines;
1003 1003@yahoo.com
;
run;

我尝试在数据步骤中使用update语句

data newEmail;
    update Email amendEmail;
    by id;
run;

虽然它只改变了id 1003的第一个观察结果。

我想要的输出是 1001 1001@gmail.com 1002 1002@gmail.com 1003 1003@yahoo.com 1003 1003@yahoo.com

是否可以使用非proc sql方法?

3 个答案:

答案 0 :(得分:2)

Vasilij基于合并的数据步骤答案将为您提供所需的数据集,但不会以最有效的方式,因为它将覆盖整个email数据集,而不是仅更新您要更改的行

您可以使用modify语句更改emailamendEmail数据集中匹配ID的行的电子邮件地址。

首先,您需要确保id数据集中的email上有索引。这只是一次性任务 - 只要您不覆盖email数据集(例如,使用另一个不使用modify语句的数据步骤,或通过排序)索引仍然会在那里。

proc datasets lib = work nolist;
    modify email;
    index create id;
    run;
quit;

现在您可以使用索引进行更新:

data email;
    set amendEmail(rename = (email = new_email));
    do until(eof);
        modify email key = id end = eof;
        if _IORC_ then _ERROR_ = 0;
        else do;
            email = new_email;
            replace;
        end;
    end;
run;

您应该在日志中看到一些如下所示的输出,表明您的数据集已更新而不是被覆盖:

NOTE: There were 1 observations read from the data set WORK.AMENDEMAIL.
NOTE: The data set WORK.EMAIL has been updated.  There were 2 observations rewritten, 0 observations added and 0 observations 
       deleted.

N.B。在使用这样的modify语句之前,请确保备份了主email数据集。如果数据步骤中断,则可能会损坏。

答案 1 :(得分:1)

如果要更改两行,最终会出现重复项。您应该首先解决源表中重复项的问题。

如果您需要具有重复结果的工作解决方案,请考虑使用带有LEFT JOIN的PROC SQL和用于电子邮件地址的条件子句。

PROC SQL;
    CREATE TABLE EGTASK.QUERY_FOR_EMAIL AS 
        SELECT t1.id, 
           /* email */
            (CASE WHEN t1.id = t2.id THEN t2.email 
            ELSE t1.email 
            END) AS email 
        FROM WORK.EMAIL t1 
        LEFT JOIN WORK.AMENDEMAIL t2 ON (t1.id = t2.id);
QUIT;

根据评论,如果您更喜欢使用数据步骤,则可以使用以下内容:

data want (drop=email2);
  merge Email amendEmail (rename=(email=email2));
  by id;
  if email2 ne "" then email=email2; 
run;

答案 2 :(得分:0)

理想情况下,您应该在by变量中包含唯一值。如果重复,它只是更新第一次观察。请参考以下链接   http://support.sas.com/documentation/cdl/en/basess/58133/HTML/default/viewer.htm#a001329152.htm