1

在数据库中,我们有如下电子邮件地址数据集。请注意,对于 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 方法?

4

3 回答 3

2

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

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

首先,您需要确保idemail数据集中有一个索引。这只是一项一次性任务——只要您不覆盖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.

注意,在您使用这样的modify语句之前,请确保您的主email数据集已备份。如果数据步骤被中断,它可能会损坏。

于 2015-08-05T19:29:25.290 回答
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;
于 2015-08-05T09:25:04.237 回答
0

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

于 2015-08-05T08:43:50.787 回答