从SAS中的大表中只选择几列

时间:2015-10-25 06:29:54

标签: sas proc-sql

我必须在一个键上加两个表(比如XYZ)。我必须使用coalesce函数更新表A中的一个单独的列。合并(a.status_cd,b.status_cd)。

表A:
包含大约100列。关键栏ABC。

表B: 仅包含2列。 KEY列ABC和status_cd

我在此左连接查询中使用的表A具有超过100列。有没有办法在我的PROC SQL中使用。*后跟这个coalesce函数,而无需从PROC SQL创建新列; CREATE TABLE AS ...步骤?

提前致谢。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

在完成几个更复杂的方法之后,我最终在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的前几个答案中。但是,目前不支持此语法 - 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语句相关的标准警告:如果此数据步骤中断,则主数据集可能会受到无法修复的损坏,因此请确保先备份。

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

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

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行。