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

How can I create a dynamic where clause in a SAS Proc Sql statement?

我想创建以下 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 宏,但没有任何效果。

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

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

data master_file;
input @1 full_String .;
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;

要将单词替换为空白,您可以使用连接 - 我在这里使用左连接,内连接只会 return 匹配的行,左连接 return 仅匹配的所有行已编辑的(这也显示了匹配的字符串):

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;

这实际上并不寻找 space 分隔符,但您的评论表明您可能不需要它。否则,您可以通过串联将其添加回去。

此外,请注意,如果匹配了多个字符串,这不一定会满足您的要求。将第四行从 5678 更改为 1234,它只会更改 1234 - 这样每行只能进行一次匹配。进行多次匹配将是一个非常不同的操作。