SAS SQL多词列表模糊搜索问题:含空格多词匹配失败求助
问题:SAS中使用CONTAINS匹配带空格的多词术语失效
我有200多个术语,需要在某表的一列中匹配这些术语是否存在。该列是包含多个值的字符串,因此我使用CONTAINS函数。以下代码在变量为单个单词时可正常运行,但遇到带空格的多词术语时无法生效。我认为需要用引号保留字符串格式,但无法确定问题出在术语列表构建、CONTAINS函数限制还是循环变量格式上,恳请指导。
%let terms = JACK JOHN SMITH JOHN JACOB SMITH; %macro doit(list); proc sql noprint; %let n=%sysfunc(countw(&list)); %do i=1 %to &n; %let val = %scan(&list,&i); INSERT INTO Name_Identifier Select Distinct "&val." as Search_Term ,a.* From SCENARIO_TBL a Where ID in ( Select ID From NAME_TABLE Where NAMES_COL contains "&val." ) %end; quit; %mend; %doit( &terms. );
问题原因
核心问题出在宏函数%COUNTW和%SCAN的默认分隔符:SAS宏函数默认以空格作为分隔符拆分字符串、统计元素数量。你的术语列表中,JOHN SMITH会被拆成JOHN和SMITH两个独立元素,JOHN JACOB SMITH会被拆成三个元素,循环时会分别处理这些单个单词,自然无法匹配原多词术语。
解决方案
方法1:修改宏函数的分隔符
用特殊字符(比如竖线|)作为术语的分隔符,避免和术语内的空格冲突:
%let terms = JACK|JOHN SMITH|JOHN JACOB SMITH; %macro doit(list); proc sql noprint; %let n=%sysfunc(countw(&list,|)); /* 指定分隔符为| */ %do i=1 %to &n; %let val = %scan(&list,&i,|); /* 指定分隔符为| */ INSERT INTO Name_Identifier Select Distinct "&val." as Search_Term ,a.* From SCENARIO_TBL a Where ID in ( Select ID From NAME_TABLE Where NAMES_COL contains "&val." ); /* 补充语句结束的分号,修复语法错误 */ %end; quit; %mend; %doit(&terms.);
方法2:用数据步预处理术语列表
如果术语数量多,维护特殊字符分隔的列表麻烦,可先把术语存入临时表,再循环读取表中术语:
/* 创建术语临时表 */ data terms_list; length term $100; input term $char.; /* $char.格式保留术语内的空格 */ datalines; JACK JOHN SMITH JOHN JACOB SMITH ; run; %macro doit(); proc sql noprint; select count(*) into :n from terms_list; quit; proc sql noprint; %do i=1 %to &n; /* 读取第i个术语 */ proc sql noprint; select term into :val trimmed from terms_list where monotonic()=&i; quit; INSERT INTO Name_Identifier Select Distinct "&val." as Search_Term ,a.* From SCENARIO_TBL a Where ID in ( Select ID From NAME_TABLE Where NAMES_COL contains "&val." ); %end; quit; %mend; %doit();
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

