Where语句在SAS中的多个变量的任意组合中搜索2个值

Where statement searching for 2 values in any combination of multiple variables in SAS

我正在尝试使用 Proc SQl 搜索双重条件。 我想搜索何时 'TTT' AND 'RRR' 存在于 v1,v2,v3,v4...v10 所以它可能是 TTT 在 V1 中,而 RRR 在 v10 中或在 V1 和 V2 中。有很多组合,但我不想明显地输入每个组合。 同时,我还想使用 OR 语句从 v1-v10 中搜索单独包含 ('TTT' AND 'RRR') OR ('GGG') 的变量。我一直在四处寻找,认为可能是什么时候可行的​​情况,但我不这么认为,而且我需要将其设为 PROC SQL。

我知道下面的代码是错误的,因为它是一个较长的版本,但是,只是为了理解我的意思:

WHERE date BETWEEN &start. AND &end. 
AND ( ((V1 = 'TTT' and V2 ='RRR') OR (V1 = 'GGG')) OR ((V1 = 'TTT' and V3 ='RRR') OR (V1 = 'GGG')) OR ((V1 = 'TTT' and V4 ='RRR') OR (V1 = 'GGG')) ...)

谢谢, 非常感谢!


基于@Tom 的回答的更新版本

 data
diag_table;
input v1 $ v2 $ v3 $ v4 $ v5 $;
cards;
TTT . . RRR .
GGG . . . .
. RRR . . TTT
. . . . .
FFF . . . .
. . RRR1 . .
TTT . . GGG .
. RRR . GGG .
run;
proc print data=diag_table;
quit;

proc sql;
create table diag_found  as
select *
from diag_table
WHERE (whichc('TTT',v1,v2,v3,v4,v5) and whichc('RRR',v1,v2,v3,v4,v5)) or (whichc('GGG',v1,v2,v3,v4,v5));
quit;
proc print data=diag_found;
quit;

此代码的唯一问题是它还会抓取行 包含GGG + RRR,和GGG + TTT 我尝试在这两个组周围添加括号,但没有任何改变。

更新: @汤姆和@乔:

是的,我想我的意思是内部带有 AND 的 XOR。

所以如果 A=TTT B=RRR C=GGG (A 和 B) 异或 C

A+B 组合或 C

谢谢!!

你可以试试正则表达式。符合以下内容:

where prxmatch('/(TTT.*RRR|RRR.*TTT)|GGG/',cats(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10));

您可以使用WHICHC()功能来做您想要的。

where whichc('TTT',v1,v2) and whichc('RRR',v1,v2)

请注意,在 SQL 中使用起来有点困难,因为您不能使用变量列表,因此您需要明确列出每个变量名称,whichc('TTT',v1,v2,v3,v4,v5),而不是仅仅使用变量列表, whichc('TTT', of v1-v5) ,就像您在数据步骤中所做的那样。

不确定你所说的 GGG 是什么意思。但是,如果你的意思是没有 TTT 或 RRR 的 GGG,那么你可以使用这样的逻辑。

where (whichc('TTT',v1,v2) and whichc('RRR',v1,v2))
   or (whichc('GGG',v1,v) and not (whichc('TTT',v1,v2) or whichc('RRR',v1,v2)))

我认为您在这里不需要特别复杂的东西;您将在 user2877959 和我的答案中看到的关键概念是将字符串连接成一个长字符串,因此您只需要一次调用(或者在我的情况下,三个简单的调用)。数据步骤比 sql 更容易,但它会以任何方式工作。

我使用带有定界符的 CATX 来确保 "RR" | "RTTT"不配,也。然后我们只使用 FIND 来查找匹配的字符串。

data have;
  input (v1-v10) (:.);
  datalines;
AAA BBB CCC DDD EEE FFF GGG HHH III JJJ
KKK LLL MMM NNN OOO PPP QQQ RRR SSS TTT
UUU VVV WWW XXX YYY ZZZ AAA BBB CCC DDD
GGG TTT RRR AAA BBB CCC DDD EEE FFF HHH
;;;;
run;

proc sql;
  select * from have
      WHERE ( 
           find(catx('|',v1,v2,v3,v4,v5,v6,v7,v8,v9,v10),'RRR') and 
           find(catx('|',v1,v2,v3,v4,v5,v6,v7,v8,v9,v10),'TTT')
          ) ne
          (find(catx('|',v1,v2,v3,v4,v5,v6,v7,v8,v9,v10),'GGG') > 0
          )
    ;
quit;

当然,如果您希望视图也可以处理 WHERE 子句。

我修改了代码以添加异或组合;基本上它包含 GGG 或 TTT+RRR 但不包含 GGG+TTT+RRR。这通过简单地比较两个布尔结果来工作(注意我将 >0 添加到第二个以使其评估为 true/false;第一个已经评估为 true/false 感谢 and).

如果您确实希望排除 GGG+RRR,则必须添加一些额外的条件;您最好将 'has RRR'、'has TTT' 和 'has GGG' 的值分配给三个变量(在视图中或在 PROC SQL SELECT 查询)然后评估那些而不是必须做一堆 find/whichn/etc.