2017-04-05 19 views
0

でチェーンの長さを数える:、私は次のようなSAS/SQLでテーブルを持っているSQL

入力私は私の長さを伝える3列目を持ちたい

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 

は「チェーン」を見つけて、その長さを計算しています。この例では、 "A-B-C-D"と "E-F"という2つのチェーンを持っています。チェーンは、チェーンの始まり(この場合は「A-B」)を有する行を最初に形成する。次に、Field2の値がBなので、Field1の値Bを探し、Field2の新しい対応する値(この場合は「B-C」)を持つ最初の行の下に書き込みます。次に、Field1に値Cが存在するかどうかをチェックし、そうであればそれを書き留めます。私たちの場合、それは「C-D」になります。ここでも、Field1に値Dが存在するかどうかをチェックします。存在しないので、次の連鎖でアルゴリズムを開始し、より多くの接続を持たない "E-F"と書くでしょう。

長さの値は、そのペアがどれほど深いかを示します。 「A-B-C」は鎖「A-B-C」の第2の対であり、「C-D」は鎖「A-B-C-D」の第3の対である。

私は解決策、これを達成するための任意の助けに来ることができません?この形式で正確に記述する必要はありません。回避策も大きな助けになります。

ある行については、Field1 = Field2であることは決してありません。

ありがとうございます!

+1

再帰的なCTEが必要です。 SASにはまだIIRCはありません。 – wildplasser

答えて

0

SASのSQL実装では不可能です。

データステップでこれを行う方法はたくさんあります。あなたがハッシュを理解するなら、おそらくハッシュオブジェクトは最も簡単です。ハッシュイテレータを使用してハッシュから最初の行を取得し、次にfield2と一致する行を取得します。フィールド2に一致する行がない場合は、探し出してイテレータが次の行を引き出します。

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; 
関連する問題