SASでは、当然のことながらテーブルの結合は欠かせません。
DATAステップで行うのであれば、
縦結合の場合はSETステートメント、横結合の場合はMERGEステートメントが一般的です。
SQL(SQLプロシジャ)でもそのほとんどの処理(あるいはそれ以上の処理)を
記述することができます。
今回は、記事のタイトルの通り、
「2つのテーブルの片方にだけ存在するキーを抽出する」方法を掲載します。
以下のようなSASデータセット『temp1』と『temp2』を使います。
『temp1.sas7bdat』
『temp2.sas7bdat』
ここでは、『temp1』にだけ存在するキーを抽出してみます。
つまり、変数KEYが5のレコードのみを抽出します。
まずは、DATAステップのMERGEステートメントでの実装例です。
data temp3_mrg ;
merge temp1(in=in1) temp2(in=in2) ;
by key ;
if in1 and ^in2 ;
run ;
これは基本ですね。
IN=オプションで、「in1」「in2」という変数名をMERGEステートメントで指定して、
BYステートメントでは結合キー(ここでは変数KEY)を指定します。
サブセット化IFステートメントでは、結合の際の抽出条件を指定します。
『temp1』にだけ存在するレコードを抽出するので、"in1 and ^in2"という条件文になります。
出力結果は以下の通りです。
では、これと同じ結果をSQLプロシジャで出してみます。
まずは、サブクエリを使用するパターンです。
proc sql ;
create table temp3_sql1 as
select temp1.key from temp1
where not exists
(select * from temp2
where temp1.key = temp2.key
)
;
quit ;
NOT EXISTSとサブクエリを併用します。
サブクエリでは、変数KEYでマッチする『temp2』のレコードを抽出。
サブクエリの結果に対してNOT EXISTSな『temp1』のレコードを抽出。
結果、『temp1』にだけ存在するレコードが抽出されます。
次は、サブクエリを使用しない方法です。
LEFT JOIN(左外部結合)とWHERE句の組み合わせで可能になります。
proc sql ;
create table temp3_sql2 as
select temp1.key
from temp1 left join temp2
on temp1.key = temp2.key
where temp2.key = .
;
quit ;
左外部結合は、左側のテーブル(ここでは『temp1』)を優先して全レコードを出力します。
それだけでは、『temp1』のレコードが全て抽出されるだけなので、
抽出条件をWHERE句に記述します。
ここでは、『temp1』にだけ存在する変数KEYを出力したいので、
"temp2.key = .(←欠損値)"という抽出条件を追加します。
なぜ、このような条件文になるかというと、
まず、変数KEYが1~3のときは、『temp2』にも同じ値が存在するので条件文を満たしません。
次に、変数KEYが5のときは、『temp2』に同じ値が存在しないので『temp2』の変数KEYは欠損値になります。
(ちなみに、『temp2』だけに存在する値(ここでは4)は、結合方法が左外部結合なので評価されません。)
参考までに、両方の実行ログと出力結果を載せておきます。
[google]
0 件のコメント:
コメントを投稿