SAS:从一个表插入另一个表

时间:2016-11-10 19:02:43

标签: sas

我想要使用单独分析的结果更新数据集。分析在循环中完成。在循环结束时,将使用分析中的值更新主数据集。但是,我很难将新值插入主表。

对于这个例子,我已经删除了循环。另外,我不是覆盖主数据集,而是创建副本。

主数据集有两个变量,用于标识哪些行需要插入值,var1var2

data master;
  input var1 $ var2 $;

  datalines;
  A A
  A A
  A B
  A B
  ;
run;

由于结果是循环的一部分,因此插入必须单独执行。也就是说,我无法将分析结果合并到一个表中并执行一次合并。我在这里将它们作为两个单独的数据集给出了它们。

data first_insert;
  input var1 $ var2 $ var3 $;

  datalines;
  A A C
  ;
run;

data second_insert;
  input var1 $ var2 $ var3 $;

  datalines;
  A B D
  ;
run;

我的第一种方法是使用MERGE语句。但是,当我这样做时,并非所有数据都写入主表。

*****************;
** Using Merge **;
*****************;

data master_merge_copy;
  set master;
run;

data master_merge_copy;
  merge master_merge_copy
        first_insert
        ;
  by var1 var2;
run;

这会按照我的预期进行合并,将值C放在var3 var1 = A AND var2 = A的位置。

Obs    var1    var2    var3
1      A       A       C
2      A       A       C
3      A       B
4      A       B

但是,当我执行第二次合并时,只会写入与合并条件匹配的第一个观察。我需要将var3 = D写入var1 = A AND var2 = B的所有观察。

data master_merge_copy;
  merge master_merge_copy
        second_insert
        ;
  by var1 var2;
run;

                             Obs    var1    var2    var3
                              1      A       A       C
                              2      A       A       C
                              3      A       B       D
                              4      A       B

其次,我尝试使用UPDATE语句。

******************;
** Using Update **;
******************;
data update_copy;
  set master;
run;

data update_copy;
  update update_copy
         first_insert
         ;
  by var1 var2;
run;

但是,BY组中存在多个观察会产生错误。

WARNING: The MASTER data set contains more than one observation for a BY group.
var1=A var2=A var3=  FIRST.var1=0 LAST.var1=0 FIRST.var2=0 LAST.var2=1 _ERROR_=1 _N_=2
WARNING: The MASTER data set contains more than one observation for a BY group.
var1=A var2=B var3=  FIRST.var1=0 LAST.var1=1 FIRST.var2=0 LAST.var2=1 _ERROR_=1 _N_=4

结果数据集不像我期望的那样:

                             Obs    var1    var2    var3

                              1      A       A       C
                              2      A       A
                              3      A       B
                              4      A       B

似乎可能有PROC SQL使用INSERTWHERE语句的解决方案。但是,当要插入的值位于单独的表中时,我不清楚如何执行此操作。我可以找到的所有示例都声明要显式插入的值。例如,

proc sql;
   update sql.newcountries
      set population=population*1.05
         where name like 'B%';
quit;

请指教!

3 个答案:

答案 0 :(得分:2)

不要插入任何东西。生成新记录并将它们附加到您正在生成的新结果文件中。首先确保all_results不存在。然后在你的循环中将当前结果附加到它。因此,您的示例数据将是这些步骤。

 proc append base=all_results data=first_insert force;
 run;
 proc append base=all_results data=second_insert force;
 run;

现在,您可以通过将此表与主表合并来创建所需的整体结果。

data want ;
   merge master all_results;
   by var1 var2;
run;

答案 1 :(得分:0)

似乎LewisC_sas能够在SAS论坛上提供类似问题的答案。 SAS SQL的语法让我觉得奇怪,但以下似乎有效。

data master;
  input var1 $ var2 $;

  datalines;
  A A
  A A
  A B
  A B
  ;
run;

data first_insert;
  input var1 $ var2 $ var3 $;

  datalines;
  A A C
  ;
run;

data second_insert;
  input var1 $ var2 $ var3 $;

  datalines;
  A B D
  ;
run;

data master_copy;
  set master;
  length var3 $ 8.;
run;

proc sql;
  update master_copy A
  set var3 = ( select var3
  from first_insert
  where A.var2 = var2)
  where var2 in (select var2
  from first_insert);
  ;
quit;

proc sql;
  update master_copy A
  set var3 = ( select var3
  from second_insert
  where A.var2 = var2)
  where var2 in (select var2
  from second_insert);
  ;
quit;

请注意,如果在循环内部实现此操作,请确保仅复制master_copy一次!

答案 2 :(得分:0)

我不喜欢使用SQL,因为它写起来相当烦人。我也不喜欢使用数据步骤合并技术(它确实存在),因为它们也非常难以记住语法,至少对我而言。

数据步骤哈希在我看来是最好的。

data want;
  if 0 then set first_insert;
  if _n_=1 then do;
    declare hash f(dataset:'first_insert');
    f.defineKey('var1','var2');
    f.defineData('var3');
    f.defineDone();
  end;
  call missing(of _all_); *prevents us from getting bit by the automatic RETAIN if `var3` is not on the master dataset;
  set master;
  rc = f.find();

run;

当然,我认为真正最好的答案是将所有修改存储到最后,然后将它们附加,如果可以的话,但有时候因任何原因都不可行。