【问题标题】:SAS update multiple records for a by groupSAS按组更新多条记录
【发布时间】:2017-08-07 23:15:35
【问题描述】:

我有一个主 A 和事务集 B。我正在尝试通过变量 C 用 B 中的记录更新 A 中的记录。

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

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

指定的 BY 组有多个记录

只有这些重复项中的第一条记录会被更新。 有没有办法告诉 SAS 更新所有这些? 还是有其他完全不同的方式?

任何帮助表示赞赏。

【问题讨论】:

  • 发布一些示例数据。如果表 A 不是变量 C,那么表 A 的唯一标识符是什么?是否要将 A 中的值替换为 C 中的变量?或当 B 缺少变量值时,您是否希望保留 A 的原始值,而不是将值设置为缺失值。
  • 问题是我在表 A 中的唯一键基于变量 C 和 D。但我的事务表中只有变量 C。这就是为什么我只用 C 来更新它。
  • 正如 SAS 文档所说:如果主数据集中存在重复项,则仅更新第一次出现,因为生成的 WHERE 语句总是在主数据集中找到第一次出现。但我真的希望有另一种方式。

标签: sql sas duplicates sql-update proc


【解决方案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;

【讨论】:

  • 太棒了,正是我想要的。谢谢!
【解决方案2】:

如果您真的想应用交易,那么扩展您的交易文件以包含关键变量 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 中的公式。如果你有多个额外的变量,那么也要重命名它们并添加额外的赋值语句来处理它们。

【讨论】:

  • 很棒的创意答案,我没有想到这个!我只会添加 BY C D;和如果 D;谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 2016-05-01
  • 2013-05-02
  • 2014-03-04
  • 1970-01-01
  • 2015-12-07
  • 2017-04-06
相关资源
最近更新 更多