Macros 定义固定SAS宏变量

Macros 定义固定SAS宏变量,macros,sas,Macros,Sas,我正在尝试运行宏,但我不确定它是否会解决,因为我有一段时间没有连接到数据库。我想知道宏的编写是否正确,是否能够解析代码每次传递的状态(即重复执行并为每个状态创建一个表) 我想知道的第二件事是,我是否可以通过from语句运行宏。例如,让entpr成为我从中提取的数据库。是否正确解决以下问题: proc sql; select * from entpr.&state.; /*Do I need the . after &state?*/ 我的代码的其余部分:

我正在尝试运行宏,但我不确定它是否会解决,因为我有一段时间没有连接到数据库。我想知道宏的编写是否正确,是否能够解析代码每次传递的状态(即重复执行并为每个状态创建一个表)

我想知道的第二件事是,我是否可以通过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;

如果
&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就能够识别宏名称的结束位置。有些人总是包含它,个人而言,除非需要,否则我将其忽略。

从多个表中选择数据时,这些表的名称本身包含一些数据(在您的情况下是状态),您可以使用以下数据来堆叠数据:

  • SQL
  • 在数据步骤中设置
只要您正在堆叠数据,您还应该向查询选择中添加一个跟踪状态的新列

考虑在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表中的列在列顺序和类型方面不相同,请使用
联合所有相应的
,让SQL过程为您排列列。

通常,我们不建议在SAS中拆分数据集。通常的原因是为了最终导出而拆分,但使用单个数据集更容易。你为什么认为你需要拆分它?如果您搜索拆分为子集,您会发现许多示例说明如何执行此操作,以及我的建议,最佳做法是不要执行此操作。请参见示例3。我需要拆分数据集的原因是,每个数据集都是从不同的表中提取的。