2017-05-25 10 views
3

私は通常、日付条件(つまり、target_dateはstart_dateとend_dateの間にある)を持つテーブルに参加するときにPROC SQLを使用します。PROC SQLのハッシュ結合相当額

私は成功した内部結合考慮する際にハッシュ結合にこれを変換することができました:

と同じものである
data hash_join; 
if _n_ = 1 then do; 
    declare hash add1(dataset:'table_2',multidata: 'Y'); 
    add1.defineKey('key_1'); 
    add1.defineData('start_date','end_date','value_1'); 
    add1.defineDone(); 
end; 

format 
    start_date date9. 
    end_date date9. 
    value_1 10.5 
; 

set table_1 (keep=key_1 target_date); 

if add1.find() = 0 then do until (add1.find_next()); 
    if start_date le target_date le end_date then output; 
end; 
run; 

proc sql; 
create table sql_join as select 
b.start_date, 
b.end_date, 
b.value_1, 
a.key_1, 
a.target_date 
from table_1 a 
inner join table_2 b 
on a.key_1 = b.key_1 and 
a.target_date between b.start_date and b.end_date 
;quit; 

私はトラブル把握を持っています左の結合に相当するものが何であるかを調べる。

if add1.find() ne 0 then output; 

そして、それは参加すると日付が同様に簡単なようであること、の間にある場合:

if add1.find() = 0 then do until (add1.find_next()); 
    if start_date le target_date le end_date then output; 
end; 
何かが参加していない場合たとえば、私は、私は簡単だと思うこれは、出力したいと思います

しかし、テーブル_1の残りのレコードは、参加する可能性がありますが、start_dateとend_dateの間にtarget_dateはありません。たとえば、table_2が販売の開始日と終了日で、その販売が2月1日までkey_1 = '服装'のために開始されなかったとします。 1月1日にtable_1に「Clothes」と売上がある場合は、キーに参加しますが、空白の値を出力します。これを行う方法に関するアイデア?

ご協力いただければ幸いです。

答えて

3

あなたは一致するかどうかを追跡する必要があります。あなたが物事の間の '間'の部分を追跡するためにハッシュ検索を使用していないので、あなたはそれを使うことができないので、あなたはそれを自分で行う必要があります。

この例を参照してください。ここでは、SASHELP.CLASSを入力テーブルのように変更して、何かが見つかったかどうかを確認するロジックを追加します。

data table_1; 
    set sashelp.class; 
    rename age=target_date name=key_1; 
    drop height weight; 
run; 

data table_2; 
    set sashelp.class; 
    do _i = 1 to mod(_n_,3); 
    start_date = age-3+_i; 
    end_date = age+1-_i; 
    if start_date le end_date then output; 
    end; 
    rename name=key_1 height=value_1; 
    keep height weight start_date age end_date name; 
run; 

data hash_join; 
if _n_ = 1 then do; 
    declare hash add1(dataset:'table_2',multidata: 'Y'); 
    add1.defineKey('key_1'); 
    add1.defineData('start_date','end_date','value_1'); 
    add1.defineDone(); 
end; 

format 
    start_date date9. 
    end_date date9. 
    value_1 10.5 
; 

set table_1 (keep=key_1 target_date); 

if add1.find() = 0 then do until (add1.find_next()); 
    if start_date le target_date le end_date then do; 
     found=1; 
     output; 
    end; 
end; 
call missing(of value_1); *full list of values to clear - all of hash data elements; 
if not (found) then output; 
run; 
+0

私の子供たちは「JINX」と言うでしょう。 – DomPazz

+1

笑。ええ、かなり印象的に似たようなコードを私たちが別々に行ったのですが...私の上にあなたのものを貼り付けていますが、私のサンプルデータを使うと正しく動作します。 – Joe

+0

ありがとうございました! – Derek

3

私はあなただけの何かがキーを持っている場合は追跡する必要があると思うんが、ない範囲で:でテストする

if add1.find() ^=0 then output; 
else do; 
    found = 0; 
    do until (add1.find_next()); 
     if start_date le target_date le end_date then do; 
      output; 
      found=1; 
     end; 
    end; 
    if ^found then output; 
end; 

データはありませんので、これは私だけではSOでコーディングされます。それが動作しない場合は教えてください。

関連する問題