2017-04-05 2 views
0

에 체인의 길이를 개수 :나는 다음과 같은 SAS/SQL에서 테이블을 SQL

입력 내가 나에게 길이를 알려주는 세 번째 열을 갖고 싶어

Field1 Field2 
A  B 
E  F 
C  D 
B  C 

Field1과 Field2로 만들 수있는 "체인" 예를 들어 설명하겠습니다. 우리의 경우, 내가 원하는 것 :

출력

Field1 Field2 Length 
A  B  1 
B  C  2 
C  D  3 
E  F  1 

이것이 할 것입니다 것은 "체인"을 찾아 길이를 계산합니다. 예제에서 우리는 2 개의 사슬, 즉 "A-B-C-D"와 "E-F"를 가질 것입니다. 체인은 처음에는 체인의 시작 부분 (이 경우 "A-B")을 가지고 행이 형성됩니다. 그런 다음 Field2의 값이 B이기 때문에 Field1의 값 B를 찾고 첫 번째 행 아래 Field2의 새 해당 값 (이 경우 "B-C")을 사용하여 값을 씁니다. 그런 다음 Field1에 값 C가 있는지 확인한 다음 해당 값이 적어 지는지 확인합니다. 우리의 경우에는 "C-D"가됩니다. 다시, Field1에 값 D가 있는지 확인합니다. 존재하지 않기 때문에 다음 체인으로 알고리즘을 시작하고 더 많은 연결이없는 "E-F"를 작성합니다.

길이 값은 그 쌍이 얼마나 깊은지를 나타냅니다. "A-B"는 첫 번째 쌍이고 "B-C"는 "A-B-C"체인의 두 번째 쌍이며 "C-D"는 "A-B-C-D"체인의 세 번째 쌍입니다.

나는 이것을 해결하기위한 해결책을 찾을 수 없다. 이 양식을 정확하게 작성할 필요는 없으며 모든 해결 방법도 큰 도움이됩니다.

주어진 행의 경우 중요한 것은 Field1 = Field2가 아닌 경우입니다.

감사합니다!

+1

재귀 적 CTE가 필요합니다. SAS는 아직 IIRC가 없습니다. – wildplasser

답변

0

SAS의 SQL 구현에서는 불가능합니다.

데이터 단계에서이를 수행 할 수있는 많은 방법. 해시 객체는 아마도 해시를 이해하면 가장 쉽습니다. 해시 반복기를 사용하여 해시에서 첫 번째 행을 가져온 다음 field2와 일치하는 행을 가져옵니다. field2와 일치하는 행이 없으면 찾고 중지하고 다음 반복자를 당겨 봅니다.

data have; 
input Field1 $ Field2 $; 
datalines; 
A  B 
E  F 
C  D 
B  C 
;;;; 
run; 

data want; 
    if 0 then set have; 
    declare hash h(dataset:'have', ordered:'a'); 
    h.defineKey('field1'); 
    h.defineData('field1','field2'); 
    h.defineDone(); 
    declare hiter hi('h'); 

    do rc = hi.next() by 0 while (rc=0); *outside iterator - grab the next available row; 
    seq = 1;  *initialize the sequence variable; 
    output;   *output the first row; 
    do rc_h = h.find(key:field2) by 0 while (rc_h=0); *inside seek - looks for a row (anywhere) that matches field2.; 
     seq=seq+1; *increment the sequence variable; 
     output;  *output this row; 
     rc_r = h.remove();   *remove that row from the hash as it has been "used"; 
     rc_h = h.find(key:field2); *look to see if there is another match in this sequence; 
    end; 
    rc = hi.next(); 
    end; 
    stop; 
    drop rc:; 
run; 
관련 문제