如何在SAS Proc Sql语句中创建动态where子句?

时间:2016-07-07 18:13:26

标签: sql sas sas-macro

我想创建以下Proc SQL语句:

%macro query(from_table, return_table, variable);

Proc sql;
    create table &return_table as
        select
        *
    from &from_table
    where &variable contains " 0000 "
    or &variable contains " 3023 "
    or &variable contains " 9999 "
    or &variable contains " 5555 "
    ...
    ;
run;

%mend;

我有一个400位4位数代码观测数据文件。如何遍历数据文件并创建自定义where子句。我不想输入"or &variable contains " xxxx " " 400次。

我正在考虑使用另一个宏来创建一个带有do循环的文本变量来迭代400个观察结果,但似乎无法使其工作。我想要像

这样的东西
%macro append_string(table);
    %Let string = ;
    %Do I=1 %To 400;
       %Let string = &string cat("or variable contains" , table[I]);
    %end;
%mend;

接近这个的正确方法是什么?我尝试用很多不同的方式编写append_string宏,但没有任何作用。

1 个答案:

答案 0 :(得分:1)

您可以使用exists查询来轻松完成此操作:

data substrings;
input substring $;
datalines;
1234
5678
9012
;;;;
run;

data master_file;
input @1 full_String $15.;
datalines;
1234 58328 2148
9485 12345 9845
9012 19484 1234
5678 56789 9019
9999 99999 9999
;;;;
run;

proc sql;
  select * from master_file M
    where exists (
      select 1 from substrings S
      where findw(M.full_string, trim(S.substring))
      )
    ;
quit;

要用空格替换单词,可以使用连接 - 我在这里使用左连接,内连接只返回匹配的行,左连接返回所有只编辑匹配的行(这也显示匹配的字符串) :

proc sql;
  select M.full_string, S.substring, tranwrd(M.full_string,trim(S.substring),' ')
  from master_file M
       left join substrings S
       on findw(M.full_String,trim(s.substring))
  ;
quit;

这实际上并不寻找空格分隔符,但是您的评论表明您可能不需要它在那里。否则,您可以通过连接将其重新添加。

另外,请注意,如果匹配多个字符串,则不一定能够执行此操作。将第四行从5678更改为1234,它只会更改1234 - 它只能以这种方式每行进行一次匹配。进行多次匹配将是一种非常不同的操作。