2012-12-27 3 views
1

4 개의 매우 큰 테이블이 있습니다. r은 해당 레코드에있는 경우여러 테이블/데이터 세트에서 일치하는 Oracle/SAS 레코드

테이블 X에서 기록적인 연구를 생각해 내게 다음과 같이 내가 X에서 둘 이상의 테이블의 X1과 X2를 만들려는 X, A, B와 C

을 부르 자 테이블 A, B, C 중 적어도 하나를 X1에 넣었습니다. 그렇지 않으면 X2에 넣습니다.

(어떻게 r에 A, B 또는 C에 해당 레코드가 있는지 결정하려면 r 필드 몇 개를 A, B 또는 C 레코드의 몇 필드와 비교하십시오. 필드는 A , B 또는 C가 있으며 A, B 또는 C의 레코드와 r을 일치시키는 기준이 두 개 이상있을 수 있습니다.이 부분은 주 문제와 관련이 없습니다.)

두 가지 옵션이 있습니다. 오라클 테이블 또는 SAS 데이터 세트로 X, A, B 및 C가 있습니다.

이 문제를 해결하는 가장 효율적인 방법은 무엇입니까?

안부,

+0

"매우 큰"크기는 얼마입니까? – sasfrog

+0

모든 테이블에 대해 행 수가 50M보다 많다고 가정 할 수 있습니다. –

+0

... 몇 개의 열이 있습니까? 또한,이 무언가가 당신이 많은 시간을 할 의도입니까, 아니면 일회성입니까? 일치하는 항목을 찾으면 X1과 X2를 다시 만들거나 추가 할 예정입니까? 또는 X를 선택한 후에 행이 다시 변경됩니까? – sasfrog

답변

1

Tartaglia의 답변은 매우 비슷하지만 한 단계에서 쉽게 할 수 있습니다.

data x1 x2; 
merge x(in=x) a(in=found keep=id) b(in=found keep=id) c(in=found keep=id); 
by id; 
if x and found then output x1; 
else if x then output x2; 
run; 

은 '발견'하고 있는지 확인 'X'어떤 원본 데이터 셋에없는 변수가 다른 뭔가가 사용됩니다 유일한 당신이 A, B, C에서 ID 이외의 변수를 원하는 경우 요소가 복잡하게; 그렇다면 다중 일치 시나리오가있는 경우 올바른 변수를 얻을 수있는 방법을 찾아야합니다. 네 개의 모든 테이블을 정렬해야합니다 (느려질 수도 있음).

다른 SAS 솔루션 : 해시 테이블. 이것은 이 아니며은 데이터 집합을 정렬해야합니다.데이터 집합이 아직 순서가 맞지 않은 경우 더 빠릅니다. 그러나 테이블 A, B 및 C 모두를 메모리에 저장하는 데 충분한 메모리가 필요합니다. 이러한 테이블은 해당 데이터 세트의 크기에 따라 제한 될 수 있습니다. a, b, c가 비슷한 크기가 아닌 x보다 상대적으로 작을수록 좋습니다. 이것은 defineData를 사용하여 반환 코드가 아닌 a/b/c에서 데이터를 산출하도록 조작 할 수 있지만 다시 a, b, c 중 두 가지에서 찾은 경우 수행 할 작업에 대해 생각해야합니다 (또는 세 개 모두).

data abc/view=abc; 
set a b c; 
keep id; 
run; 

data x1 x2; 
if _n_ = 1 then do; 
declare hash abc(dataset:"abc"); 
abc.defineKey("id"); 
abc.defineDone(); 
call missing(id); 
end; 
set x; 
rc = abc.find(); 
if rc=0 then output x1; 
else output x2; 
run; 

는, 오라클에 내가 그것을 타르의 솔루션에 가까운 무언가를하는 것입니다 거라고 생각하는 방법을 수행하는 방법 - 세 '경기'테이블을 생성을 한 후 노동 조합을 (노조의 중복을 제거)하고, 그런 다음 x2를 x 빼기 x1 테이블로 작성하십시오.

create table x1 as 
    select x.* from x,a where x.id=a.id 
    union 
    select x.* from x,b where x.id=b.id 
    union 
    select x.* from x,c where x.id=c.id 
; 
create table x2 as 
    select * from x except select * from x1; 

내가 오라클에서하지만 더 나은 조금있을 수 있습니다 SQL 솔루션을 포함하여 (SAS를 사용하여이 밖으로 테스트 : IE는 (오라클 정확히 제외가 같은 경우이, SAS의 PROC의 SQL에서 확실하지 작동) 유사한 주문이어야합니다. 오라클 서버가 sas 서버보다 빠르면 일부 변경 될 수 있습니다.

5e7 레코드가있는 데이터 세트 'x'와 공정한 중복이있는 'a' 'b' 'c'데이터 세트 3 개 사용 (아마도 25 % 정도의 레코드가 2 개 이상의 데이터 세트에 있고 84 %가 하나에 있습니다 또는 그 이상), 1.5e7과 3e7 레코드 사이 (특히 하나는 홀수이고 하나는 홀수이고 하나는 3의 배수, 하나는 4의 배수), SQL 솔루션은 처리하는 데 5 분 이상 걸렸습니다. 병합 솔루션은 정렬에 약 2.5 분, 병합에 약 0.5 분이 걸렸으므로 총 약 3 분이 소요되었습니다. 이것은 데이터 세트가 정렬되어 생성 될 때 약간 과장 될 수 있으므로 정렬 자체가 다소 빨라질 수 있습니다 (SQL은 데이터 세트에서 일부를 순서대로 얻지 만).

5e7 데이터 세트 x에 대해 약 5 초의 쓰기 시간과 비교됩니다.

해시 솔루션은 전체 랩톱의 메모리에 맞지 않습니다 ~ ~ 6e7 레코드 데이터 집합 abc, 그래서 나는 ~ 2e7 합계를 줄였습니다 (그래서 1에서 2e7까지의 확률, 3의 배수 2e7에서 4e7까지, 4e7에서 6e7까지 4의 배수) 5e7 레코드가있는 x를 남겨 둡니다. 해시 솔루션은 유사한 시간이 소요되는 정렬 및 병합 솔루션과 비교하여 총 1 분 41 초가 걸렸습니다. 대부분은 x (약 1 분)를 정렬하고 결과 데이터 집합을 병합/기록 (약 1 분 30 분) . 큰 데이터 세트를 정렬하는 것보다 훨씬 빠릅니다. 작은 데이터 세트는 메모리에서 정렬되므로 큰 데이터 세트는 정렬 할 수 없습니다. SQL 솔루션은 이러한 데이터 세트로 약 4 분이 걸렸으므로 여전히 상당히 느립니다.

0

나는이 같은 것을 할 수있는, 제대로 이해 경우. 당신이 일치하는 항목을 찾으려면 변수에

병합 데이터 세트의 X와를 일치 X에서 출력 기록을 양식 A를 X1에 기록하고 과 일치하지 않는 양식을 X2에 출력하십시오.

당신은 예를 들어, 데이터 집합 X와 함께 다루고 말할 수 있습니다 :

data x; 
input id some_value $; 
datalines; 
1 a 
2 b 
3 c 
4 d 
5 e 
run; 

data a; 
input id some_value $ some_value_2 $; 
datalines; 
1 a x 
4 d v 
5 g u 
run; 

지금, 당신은 다음과 같이 병합 작업을 수행 할 수 있습니다 데이터 세트 B와 C에 대한

data x1_a x2_a; 
merge x(in=table_x) a(in=table_a keep=id some_value); 
by id some_value; 
if table_x = 1 and table_a = 1 then output x1_a; 
if table_x = 1 and table_a = 0 then output x2_a; 
run; 

반복의 by 변경 및 keep 문이있는 경우 데이터 세트 B 및 C와 일치하는 다른 규칙이 인 경우 x1_ax2_a의 이름을 x1_b 등으로 변경하면 얻을 수 없으므로 덮어 쓴.

모든 x1_ 테이블을 추가하고 질문에 설명 된대로 X1 데이터 세트가 있습니다 (중복을 처리해야 할 수도 있음).

모두를 추가하십시오. x2_ 테이블을 추가하고 고유 한 행을 계산하십시오. 과 같은 횟수만큼 나타나는 행 (이 경우 3 개, A, B, C)은 사용자가 유지하는 초기 데이터 집합입니다.

관련 문제