SQLで他のデータセットと共通、非共通のデータをとる(差集合 積集合) EXCEPT  INTERSECT

SASは1obs読み込んで処理してアウトプットするのが基本で、よくも悪くもデータの格納されている順番(ソート)に縛られているところがあります。
対してSQLは集合論ベースの言語で原則的にデータの格納位置(アドレス)に縛られない書き方ができます。

今以下のような2つのデータセットがあるとします。

data Q_1;
input X $ Y $ Z $;
cards;
A C D
D B C
C A B
B B A
C A C
A C A
B A C
;
run;



data Q_2;
input X $ Y $ Z $;
cards;
D C D
D B C
C A B
B F A
C A C
C C A
F A C
;
run;


今Q_1について、Q_2に同じ内容のオブザベーションのあるレコードのみを抽出したいとします。
その場合、

proc sql;
 create table A_1 as
 select *
  from Q_1

 intersect corr all

 select *
   from Q_2
;
quit;






二つの抽出文をintersectで繋ぐことで共通のデータを残すことができます。

これをSASで書くなら
MergeのQ_2にin=をつけてQ_2からデータが読み込まれたらフラグがたつようにして
X Y Zを全部BYに指定して、in=が1になるデータだけを残す感じです。

この場合においては僕はSQLの方が、やりたいことの本質にあった、見通しのよい
コードになっていると思います。

また同様に、Q_1からQ_2と共通でない、かぶってないデータを欲しい場合は

proc sql;
 create table A_2 as
 select *
  from Q_1

 except corr all

 select *
  from Q_2
;
quit;


のようにexceptで繋ぎます。

allは重複を勝手にけさない、corrは処理の時にきちんと変数名をみてやってください的な
役割です。


何かやりたいことがあるとき、データステップでやるかSQLでやるか迷った場合は
やりたいことをイメージ化してみるのがいいと思います。

思い浮かんだのがフロー図であれば、データステップ
ベン図ならSQLって感じで。







0 件のコメント:

コメントを投稿