select SAS 中的大型 table 只有几列

select only a few columns from a large table in SAS

我必须在一个键上加入 2 tables(比如 XYZ)。我必须使用合并函数更新 table A 中的一个列。合并(a.status_cd,b.status_cd)。

TABLE答:
包含大约 100 列。关键列 ABC。

TABLE乙: 仅包含 2 列。 KEY 列 ABC 和 status_cd

TABLE 我在这个左连接查询中使用的 A 有超过 100 列。有没有一种方法可以在我的 PROC SQL 中使用 a.* 后跟此合并函数,而无需从 PROC SQL 中创建新列; CREATE TABLE AS ...步骤?

提前致谢。

在尝试了几种更复杂的方法后,我最终在 proc sql 中找到了一种相当简单的方法:

proc sql noprint;
  update master a
  set status_cd= coalesce(status_cd,
                           (select status_cd
                            from transaction b
                            where a.key= b.key))
  where exists (select 1
                from transaction b
                where a.ABC = b.ABC);
quit;              

这将只更新您感兴趣的一列,并且只会更新其键值在交易数据集中匹配的行。

之前的尝试:

更通用的 SQL 语法中最明显的一点似乎是 update...set...from...where 模式,它在 this question. However, this syntax is not currently supported - the documentation for the SQL update statement 的前几个答案中使用,只允许 where 子句,而不是 from 子句。

如果您是 运行 对支持此语法的另一个数据库的传递查询,它可能仍然是一个可行的选择。

或者,有一种方法可以通过数据步骤在 SAS 中执行此操作,前提是主数据集已在您的关键变量上建立索引:

/*Create indexed master dataset with some missing values*/
data master(index = (name));
  set sashelp.class;
  if _n_ <= 5 then call missing(weight);
run;

/*Create transaction dataset with some missing values*/
data transaction;
  set sashelp.class(obs = 10 keep = name weight);
  if _n_ > 5 then call missing(weight);
run;

data master;
  set transaction;
  t_weight = weight;
  modify master key = name;
  if _IORC_ = 0 then do;
      weight = coalesce(weight, t_weight);
      replace;
  end;
  /*Suppress log messages if there are key values in transaction but not master*/  
  else _ERROR_ = 0; 
run;

modify 语句相关的标准警告:如果此数据步骤被中断,则主数据集可能会受到无法修复的损坏,因此请确保先备份。

在这种情况下,我假设键变量是唯一的 - 如果不是,则需要稍微复杂的数据步骤。

另一种解决 proc sql update 语句中缺少 from 子句的方法是设置格式合并,例如

data v_format_def /view = v_format_def;
    set transaction(rename = (name = start weight = label));
    retain fmtname 'key' type 'i';
    end = start;
run;

proc format cntlin = v_format_def; run;

proc sql noprint;
    update master 
        set weight = coalesce(weight,input(name,key.))
        where master.name in (select name from transaction);
run;

在这种情况下,我在格式定义中使用了 type = 'i' 来创建一个数字信息,proc sql 使用它来将字符变量 name 转换为数字变量 weight。根据您的 keystatus_cd 列是字符还是数字,您可能需要稍微不同地执行此操作。

这种方法在使用格式时有效地将整个交易数据集加载到内存中,如果您有非常大的交易数据集,这可能会成为问题。数据步骤方法应该几乎不使用任何内存,因为它一次只需要加载 1 行。

您可以利用数据集选项来创建它,以便您可以在 select 语句中使用通配符。请注意,这样做可能会改变列的顺序。

proc sql ;
  create table want as
    select a.*
         , coalesce(a.old_status,b.status_cd) as status_cd
    from tableA(rename=(status_cd=old_status)) a
    left join tableB b
      on a.abc = b.abc
  ;
quit;