【问题标题】:SAS PROC SQL NOT CONTAINS multiple values in one statementSAS PROC SQL 在一个语句中不包含多个值
【发布时间】:2016-11-11 10:28:02
【问题描述】:

在 PROC SQL 中,我需要选择名为“NAME”的列不包含多个值“abc”、“cde”和“fbv”的所有行,无论这些值之前或之后是什么。所以我这样做了:

SELECT * FROM A WHERE
  NAME NOT CONTAINS "abc" 
  AND
  NAME NOT CONTAINS "cde"
  AND
  NAME NOT CONTAINS "fbv";

这很好用,但我想如果我们有一百个条件会很头疼。所以我的问题是 - 我们可以在 PROC SQL 中的单个语句中完成此操作吗? 我试过用这个:

SELECT * FROM A WHERE 
  NOT CONTAINS(NAME, '"abc" AND "cde" AND "fbv"');

但这在 PROC SQL 中不起作用,我收到以下错误:

错误:找不到函数 CONTAINS。

我不想使用 LIKE。

【问题讨论】:

    标签: sql sas proc-sql


    【解决方案1】:

    我想你可以使用正则表达式。

    data a;
    input name $;
    datalines;
    xyabcde
    xyzxyz
    xycdeyz
    xyzxyzxyz
    fbvxyz
    ;;;;
    run;
    
    proc sql;
    
    SELECT * FROM A WHERE
      NAME NOT CONTAINS "abc" 
      AND
      NAME NOT CONTAINS "cde"
      AND
      NAME NOT CONTAINS "fbv";
    
    
    SELECT * FROM A WHERE
      NOT (PRXMATCH('~ABC|CDE|FBV~i',NAME));
    quit;
    

    但是,您不能以这种方式使用 CONTAINS。

    【讨论】:

    • 工作得很好,谢谢! ~ 表示我假设的通配符?
    • ~ 只是一个分隔符,您必须使用正则表达式中未使用的任何分隔符来开始和结束正则表达式。正则表达式匹配“任何地方”,除非您将它们锚定为开始或结束。
    【解决方案2】:

    你可以使用NOT IN:

    SELECT * FROM A WHERE 
      NAME NOT IN ('abc','cde','fbv');
    

    【讨论】:

    • 但我需要它来排除任何包含例如的记录'abc' 无论'abc' 之前或之后有多少个字符。
    【解决方案3】:

    如果项目的数量高于构建内部代码的合理数量,您可以创建一个表(下面的 work.words)来存储单词并对其进行迭代以检查出现情况:

    data work.values;
    input name $;
    datalines;
    xyabcde
    xyzxyz
    xycdeyz
    xyzxyzxyz
    fbvxyz
    ;
    run;
    
    data work.words;
    length word $50;
    input word $;
    datalines;
    abc
    cde
    fbv
    ;
    run;
    
    
    data output;
    set values;
    
    /* build a has of words */
    length word $50;
    if _n_ = 1 then do;
       /* this runs once only */
       call missing(word);
       declare hash words (dataset: 'work.words');
       words.defineKey('word');
       words.defineData('word');
       words.defineDone();
    end;
    
    /* iterate hash of words */
    declare hiter iter('words'); 
    rc = iter.first();
    found = 0;
    do while (rc=0); 
       if index(name, trim(word)) gt 0 then do; /* check if word present using INDEX function */
          found= 1;
          rc = 1;
       end;
       else rc = iter.next();
    end;
    if found = 0 then output; /* output only if no word found in name */
    drop word rc found;
    run;
    

    【讨论】:

      猜你喜欢
      • 2021-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      相关资源
      最近更新 更多