Sql SAS按组更新多个记录

Sql SAS按组更新多个记录,sql,sas,duplicates,sql-update,proc,Sql,Sas,Duplicates,Sql Update,Proc,我有一个主a和事务集B。我试图用变量C将a中的记录和B中的记录合并 DATA TEST; UPDATE A B; BY C; RUN; 问题是,我的主数据集中有一些重复的记录,我仍然想更新它们。但我得到的是一个警告 指定的组有多条记录 而且只有这些副本中的第一条记录得到更新。 有没有办法告诉SAS更新所有这些文件? 或者还有其他完全不同的方式吗 非常感谢您的帮助。如果您真的想应用事务,请扩展事务文件,使其包含的关键变量C、D的所有可能值与C的值相同 proc sql ; creat

我有一个主a和事务集B。我试图用变量C将a中的记录和B中的记录合并

DATA TEST;
  UPDATE A B;
  BY C;
RUN;
问题是,我的主数据集中有一些重复的记录,我仍然想更新它们。但我得到的是一个警告

指定的组有多条记录

而且只有这些副本中的第一条记录得到更新。 有没有办法告诉SAS更新所有这些文件? 或者还有其他完全不同的方式吗


非常感谢您的帮助。

如果您真的想应用事务,请扩展事务文件,使其包含的关键变量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数据集中的变量来编程。然后,您可以显式地编写代码,确定是希望操作像合并还是更新。因此,如果您的额外变量名为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值使其缺少结果)然后使用类似于“合并”中的公式。如果您希望得到更新的效果,请使用类似于“更新”中的公式。如果您有多个额外变量,请同时重命名它们并添加额外的赋值语句来处理它们。

如果您真的想应用事务,请扩展事务文件以获得该键的所有可能值变量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数据集中的变量来编程。然后,您可以显式地编写代码,确定是希望操作像合并还是更新。因此,如果您的额外变量名为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值使其缺少结果)然后使用类似于“合并”中的公式。如果您想获得更新效果,请使用类似于“更新”中的公式。如果您有多个额外变量,请同时重命名这些变量,并添加额外的赋值语句来处理它们。

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

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;

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

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;

发布一些示例数据。如果表A不是变量C,那么它的唯一标识符是什么?是否要将A中的值替换为C中的变量?或者,当B缺少某个变量的值时,是否希望保留a的原始值,而不是将该值设置为缺少。问题是表a中的唯一键基于变量C和D。但我的transactioni表中只有变量C。这就是为什么我只使用C来更新它。正如SAS文档所说:如果主数据集中存在重复项,则只更新第一个匹配项,因为生成的WHERE语句总是在主数据集中找到第一个匹配项。但我真的希望有另一种方法。发布一些样本数据。如果表A不是变量C,那么它的唯一标识符是什么?是否要将A中的值替换为C中的变量?或者,当B缺少某个变量的值时,是否希望保留a的原始值,而不是将该值设置为缺少。问题是表a中的唯一键基于变量C和D。但我的transactioni表中只有变量C。这就是为什么我只使用C来更新它。正如SAS文档所说:如果主数据集中存在重复项,则只更新第一个匹配项,因为生成的WHERE语句总是在主数据集中找到第一个匹配项。但我真的希望有另一种方式。太棒了,正是我想要的。谢谢太棒了,正是我想要的。谢谢很有创意的回答,我没想到这个!我只想加上C和D;如果是D;谢谢你,很有创意的回答,我没想到这个!我只想加上C和D;如果是D;非常感谢。