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
。根据您的 key
和 status_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;
我必须在一个键上加入 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
。根据您的 key
和 status_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;