Определение фиксированных макропеременных SAS - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь запустить макрос, но я не уверен, что он разрешится, поскольку у меня некоторое время нет подключения к базе данных. Я хочу знать, правильно ли написан макрос и будет ли он разрешать состояния при каждом прохождении кода (т.е. делать это многократно и создавать таблицу для каждого состояния).

Второе, что я хотел бы знать, - могу ли я запустить макрос через оператор 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;

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

При выборе данных из нескольких таблиц, имена которых сами содержат некоторые данные (в вашем случае состояние), вы можете сложить данные с помощью:

  • UNION ALL в 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 выстроила столбцы для вас.

0 голосов
/ 01 ноября 2018

Если &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);

Что касается вашего вопроса относительно того, включать или нет ., то правило состоит в том, что если символ, следующий за вашей макропеременной, не является -Z, 0-9 или подчеркиванием, то период является необязательным. Эти символы являются списком допустимых символов для имени макропеременной, поэтому, пока он не является одним из тех, которые вам не нужны, SAS сможет определить, где заканчивается имя макроса. Некоторые люди всегда включают это, лично я пропускаю это, если это не требуется.

...