You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:11:02