형식의 SAS 해시 조인은 부분 부분 문자열에서 SAS 해시 검색을 수행 할 수 있습니까? 'LongString를'하지만 내 목표 테이블 키가 있습니다 : LIKE 형식 또는 = :
그래서 해시 테이블 키가 포함됩니다 'LongStr'당신은에 Iterator 객체를 사용할 필요가
형식의 SAS 해시 조인은 부분 부분 문자열에서 SAS 해시 검색을 수행 할 수 있습니까? 'LongString를'하지만 내 목표 테이블 키가 있습니다 : LIKE 형식 또는 = :
그래서 해시 테이블 키가 포함됩니다 'LongStr'당신은에 Iterator 객체를 사용할 필요가
꽤 좋지는 않지만 원하는 성능 이점을 얻지 못할 수도 있습니다. 또한 문자열 길이와 테이블 크기에 따라 해시 테이블의 모든 요소를 메모리에 넣을 수 없을 수도 있습니다.
트릭은 가능한 모든 하위 문자열을 먼저 생성 한 다음 해시 테이블에서 'multidata'옵션을 사용하는 것입니다.
우리에 대해 일치 할 데이터 집합에 포함 된 단어 만들기 :
data match_attempts;
length abbrev $10;
input abbrev ;
cards;
L
Long
LongO
LongSt
LongOther
;
run;
: 우리가 검색 할 용어가 포함 된 데이터 집합을 만들기
data abbreviations;
length abbrev $10;
set keys;
do cnt=1 to length(key);
abbrev = substr(key,1,cnt);
output;
end;
run;
: 가능한 모든 문자열 생성
data keys;
length key $10 value $1;
input key;
cards;
LongString
LongOther
;
run;
을
조회 수행 :
Obs abbrev key
=== ========= ==========
1 Long LongString
2 Long LongOther
3 LongO LongOther
4 LongSt LongString
5 LongOther LongOther
몇 가지 더주의 사항 :
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;
출력 (방법 '긴'수익률이 일치주의). 해시 테이블이 like
연산자와 같은 것을 지원하지 않는 이유는 해시 테이블에 레코드를 삽입하기 전에 키를 '해시'하기 때문입니다. 조회가 수행 될 때 조회 할 값은 '해시'된 다음 해시 된 값에 일치가 수행됩니다. 값을 조금만 변경해도 값이 해시되면 완전히 다른 결과가 발생합니다. 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 덕분입니다.
을 (목표 테이블의 키 문자열 길이는 다를 수 있음) 열쇠를 통해 반복하고 자신에 의해 일치를하십시오.
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;
+ 1'd - thankyou –
해시 테이블에 대한 매우 흥미로운 통찰력에 대해 효율성을 고려하여 vasja의 응답을 받아 들여야했습니다. 두 담당자가 결합 될 수 있는지 확인하십시오 (예 : 히터 대신 다중 데이터 옵션 사용). –
실제로 테이블이 특정 크기에 도달하면 실제로 광산이 더 효율적입니다. @ vasja의 솔루션은 모든 행에 대해 O (N * M/2) 속도로 실행해야합니다. 일치하는 항목을 찾거나 찾을 때까지 반복기를 탐색해야합니다. 평균적으로 데이터 집합의 절반을 반복합니다. 광산은 초기 오버 헤드가 더 높지만, O (N) 시간에 일치하는 것을 발견 할 수 있는데, 이는 obs의 수가 증가함에 따라 훨씬 빠릅니다. 이 시간들이 무엇을 의미하는지 궁금하다면 '빅 오 (Big O)'표기법을 검색해보십시오.작은 데이터 셋의 경우 어쨌든'like '를 사용하여 SQL 조인을 사용하는 것이 더 좋습니다. 해시 테이블을 지나치게 복잡하게 만들지 마십시오. –
실제 상황을 설명합니다. 해시를 반복하기 위해 @vasjas solution 1ms가 걸리면 각 행에 대해 결과를 얻으려면 평균 0.5ms가 소요됩니다. 큰 테이블에 10M 행이 있고 SAS가 총 83 분 30 초가되는 10M 행을 탐색하는 데 30 초가 걸린다 고합니다. 내 솔루션에서 검색 할 시간은 검색 용어에 해시 함수를 적용하고 메모리에서 결과를 검색하는 비용입니다. 이는 기본적으로 아무것도 아닙니다. 따라서 동일한 10M 행에 대한 내 솔루션의 전체 시간은 SAS가 10M 행 + 설정 시간을 통과하는 데 30 초가됩니다. 희망이 도움이됩니다. –