Hash Object VS SQL
SASのHash ObjectをSQLと比較したものを記事にしました。
-
SQLとの比較
以前の記事に書いた通り、 SASのHash Objectはプログラム実行時にデータセットをメモリに格納し、キー、データの単位でテーブルルックアップを実行するオブジェクトになります。(下図参照)
Hash Objectのテーブルルックアップは基本的にFIND()メソッドを実行し、Left joinの挙動でルックアップを実行します。
set <データセットA>;
rc=<データセットB>.find();
上記の例ではデータセットAに対してデータセットBの変数の内容で更新をします。
SQLでは実行文に項目名の羅列が必要ですが、Hash Objectではその必要がありません。
今回はHash ObjectのテーブルルックアップをSQLのJOINに置き換えた場合を想定して掲載しております。それでは見ていきましょう。
Left Join
下の例はHash ObjectでLeft Joinをしたものになります。FIND()メソッドを使用してprimaryデータセットに対してsecondaryデータセットのオブザベーションを追加更新しています。
_iorc_=sec.find();
ちなみに上の_IORC_変数は宣言してもSASデータセットに直接書き込まれない自動変数です。SASシステム内で管理されている変数でありユーザが直接更新しても内部で保持しているカウンタに影響せず、かつ使用後にdropする必要がなく大変便利なので使用しています。
if _iorc_ ne 0 then call missing(y);
call missingステートメントではFIND()メソッドで合致しなかったオブザベーションに欠損値を代入しています。
例:Hash Objectでルックアップ
data primary;
input number;
cards;
10001
10002
10009
10003
10004
10005
;
run;
data secondary;
input number y;
cards;
10001 11
10003 12
10004 13
10005 17
;
run;
data main;
if _N_=1 then
do;
if 0 then
set secondary;
dcl hash sec(dataset:"secondary") x();
sec.definekey("number");
sec.definedata("number", "y");
sec.definedone();
x.definekey("number");
x.definedata("number", "y");
x.definedone();
dcl hiter seci("sec");
end;
set primary;
_iorc_=sec.find(); *1;
if _iorc_ ne 0 then call missing(y);*2;
run;
Inner Join
下の例はHash ObjectでInner Joinをしたものになります。FIND()メソッドを使用して
値が0、つまり結合対象のデータセット双方に合致するオブザベーションのみを出力しています。
if _iorc_ = 0 then output;
data primary;
input number a;
cards;
10001 1
10002 2
10009 9
10003 3
10004 4
10005 5
;
run;
data secondary;
input number b;
cards;
10001 11
10003 12
10004 13
10005 17
;
run;
data main;
if _N_=1 then
do;
if 0 then
set secondary;
dcl hash sec(dataset:"secondary") x();
sec.definekey("number");
sec.definedata("number", "b");
sec.definedone();
x.definekey("number");
x.definedata("number", "a");
x.definedone();
dcl hiter seci("sec");
end;
set primary;
_iorc_=sec.find();*1;
if _iorc_ = 0 then output;*2;
run;
次回はFULL JOINについて詳しく紹介します。