数据步骤中的更新语句

update statement in data step

在数据库中,我们有如下电子邮件地址数据集。请注意,id 1003

有两个观察值
data Email;
    input id$ email .;
    datalines;
1001 1001@gmail.com
1002 1002@gmail.com
1003 1003@gmail.com
1003 2003@gmail.com
;
run;

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

data amendEmail;
    input id$ email .;
    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 方法?

理想情况下,您应该在 by 变量中具有唯一值。如果出现重复,它只会更新第一个观察结果。请参考下面的link http://support.sas.com/documentation/cdl/en/basess/58133/HTML/default/viewer.htm#a001329152.htm

如果你想更改两行,你最终会得到重复项。您可能应该首先解决来源 table 中的重复问题。

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

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;

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

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

首先,您需要确保在 email 数据集中的 id 上有一个索引。这只是一项一次性任务 - 只要您不覆盖 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 数据集。如果数据步骤被中断,它可能会损坏。