我正在尝试运行宏,但是由于一段时间没有与数据库的连接,我不确定它是否会解决。我想知道宏是否正确编写,并且会在每次通过代码时解析状态(即重复执行并为每个状态创建一个表)。
我想知道的第二件事是我是否可以通过from语句运行宏。例如,让entpr为我要从中提取的数据库。以下内容能否正确解决:
proc sql;
select * from entpr.&state.; /*Do I need the . after &state?*/
其余的代码:
libname mdt "........."
%let state = ny il ar ak mi;
proc sql;
create table mdt.&state._members
as select
corp_ent_cd
,mkt_sgmt_admnstn_cd
,fincl_arngmt_cd
,aca_ind
,prod_type
,cvyr
,cvmo
,sum(1) as mbr_cnt
from mbrship1_&state.
group by 1,2,3,4,5,6,7;
quit;
答案 0 :(得分:1)
如果&state
包含ny il ar ak mi
,则在编写时,代码中的from
语句将解析为:from mbrship1_ny il ar ak mi
-这是无效的SQL语法。
我的猜测是您要为以下每个表运行SQL语句:
mbrship1_ny
mbrship1_il
mbrship1_ar
mbrship1_ak
mbrship1_mi
在这种情况下,最简单的宏如下所示:
%macro do_sql(state=);
proc sql;
create table mdt.&state._members
as select
...
from mbrship1_&state
group by 1,2,3,4,5,6,7;
quit;
%mend;
%do_sql(state=ny);
%do_sql(state=il);
%do_sql(state=ar);
%do_sql(state=ak);
%do_sql(state=mi);
关于您是否要包含.
的问题,规则是,如果宏变量后面的字符不是a-Z,0-9或下划线,则句点是可选的。这些字符是宏变量名称的有效字符列表,因此只要它不是您不需要的字符之一,因为SAS就能识别宏名称的结尾位置。某些人总是将其包括在内,除非需要,我个人将其保留。
答案 1 :(得分:0)
从多个表中选择数据时,这些表的名称本身包含一些数据(在您的情况下为状态),您可以使用以下方法堆叠数据:
UNION ALL
中的{li> SQL
SET
在“数据”步骤只要要堆叠数据,还应该在查询选择中添加新列以跟踪状态。
考虑此模式以在SQL中堆叠
data one;
do index = 1 to 10; do _n_ = 1 to 2; output; end; end;
run;
data two;
do index = 101 to 110; do _n_ = 1 to 2; output; end; end;
run;
proc sql;
create table want as
select
source, index
from
(select 'one' as source, * from one)
union all
(select 'two' as source, * from two)
;
该模式可以抽象到将由宏生成的SQL源代码模板中。
%macro my_ultimate_selector (out=, inlib=, prefix= states=);
%local index n state;
%let n = %sysfunc(countw(&states));
proc sql;
create table &out as
select
state
, corp_ent_cd
, mkt_sgmt_admnstn_cd
, fincl_arngmt_cd
, aca_ind
, prod_type
, cvyr
, cvmo
, count(*) as state_7dim_level_cnt
from
%* ----- use the UNION ALL pattern for stacking data -----;
%do index = 1 %to &n;
%let state = %scan(&states, &index);
%if &index > 1 %then %str(UNION ALL);
(select "&state" as state, * from &inlib..&prefix.&state.)
%end;
group by 1,2,3,4,5,6,7,8 %* this seems to be to much grouping ?;
;
quit;
%mend;
%my_ultimate_selector (out=work.want, inlib=mdt, prefix=mbrship1_, states=ny il ar ak mi)
如果inlib表中的列在列顺序和类型方面不相同,请使用UNION ALL CORRESPONDING
使SQL过程为您排列这些列。