SAS散列连接形式为LIKE或=:

时间:2012-09-10 10:28:53

标签: hash sas datastep

是否可以对部分子字符串进行SAS哈希查找?

所以哈希表键将包含:'LongString'但我的目标表键有:'LongStr'

(目标表键字符串长度可能不同)

2 个答案:

答案 0 :(得分:2)

你可以,但它不漂亮,你可能无法获得你正在寻找的性能优势。此外,根据字符串的长度和表的大小,您可能无法将所有哈希表元素都放入内存中。

诀窍是先生成所有可能的子串,然后在哈希表上使用'multidata'选项。

创建一个包含我们想要匹配的单词的数据集:

data keys;
  length key  $10 value $1;
  input key;
  cards;
LongString
LongOther
;
run;

生成所有可能的子串:

data abbreviations;
  length abbrev $10;
  set keys;
  do cnt=1 to length(key);
    abbrev = substr(key,1,cnt);
    output;
  end;
run;

创建一个包含我们要搜索的术语的数据集:

data match_attempts;
  length abbrev  $10;
  input abbrev ;
  cards;
L
Long
LongO
LongSt
LongOther
;
run;

执行查找:

data match;
  length abbrev key $10;

  set match_attempts;

  if _n_ = 1 then do;
    declare hash h1(dataset:'abbreviations', multidata: 'y');
    h1.defineKey('abbrev');
    h1.defineData('abbrev', 'key');
    h1.defineDone();

    call missing(abbrev, key);
  end;

  if h1.find() eq 0 then do;
    output;
    h1.has_next(result: r);
    do while(r ne 0);
      h1.find_next();
      output;
      h1.has_next(result: r);
    end;
  end;

  drop r;
run;

输出(注意'长'如何返回2场比赛):

Obs abbrev    key 
=== ========= ==========
1   Long      LongString 
2   Long      LongOther 
3   LongO     LongOther 
4   LongSt    LongString 
5   LongOther LongOther 

还有一些说明。哈希表不支持like运算符之类的原因是因为它在将记录插入哈希表之前'哈希'键。执行查找时,要查找的值为“hashed”,然后对散列值执行匹配。当值被散列时,即使值的微小变化也会产生完全不同的结果。以下面的例子,哈希2几乎相同的字符串产生2个完全不同的值:

data _null_;
  length hashed_value $16;
  hashed_value = md5("String");
  put hashed_value= hex32.;
  hashed_value = md5("String1");
  put hashed_value= hex32.;
run;

输出:

hashed_value=27118326006D3829667A400AD23D5D98
hashed_value=0EAB2ADFFF8C9A250BBE72D5BEA16E29

因此,哈希表不能使用like运算符。

最后,感谢@vasja提供了一些示例数据。

答案 1 :(得分:1)

你必须使用Iterator对象循环键并自己进行匹配。

 data keys;
length key  $10 value $1;
input key value;
cards;
LongString A
LongOther B
;
run;

proc sort data=keys;
by key;
run;


data data;
length short_key  $10;
input short_key ;
cards;
LongStr
LongSt
LongOther
LongOth
LongOt
LongO
LongSt
LongOther
;
run;

data match;
    set data;
    length key $20 outvalue value $1;
    drop key value rc;
    if _N_ = 1 then do;
       call missing(key, value);
       declare hash h1(dataset:"work.keys", ordered: 'yes');
       declare hiter iter ('h1');
       h1.defineKey('key');
       h1.defineData('key', 'value');
       h1.defineDone();
    end;
    rc = iter.first();/* reset to beginning */
    do while (rc = 0);/* loop through the long keys and find a match */
        if index(key, trim(short_key)) > 0 then do;
            outvalue = value;
            iter.last(); /* leave after match */
        end;
        rc = iter.next(); 
    end; 
run;