SQL:自己結合、自己非等値結合で直積から組み合わせまで

以前、
「n個の変数からm個の変数を選択する、組み合わせのデータセットを作成する方法」
http://sas-tumesas.blogspot.jp/2014/01/m.html

では、データステップで4C2の組み合わせデータセットを作りましたが、
今回はSQLで同じことをやっていきます。

自己結合は1つのデータセットを、まるで同じものが複数あるかのように見立てて結合する
やり方で、生粋のSAS使いには苦手な人が多いような気がします。

data Q1;
X='い';output;
X='ろ';output;
X='は';output;
X='に';output;
run;








今回はまず、上図のような形で縦に値を持たせたデータセットを作ります。


そして、まず直積の説明(cross joinでも可)

proc sql noprint;
 create table A1 as
  select T1.X as X1
        ,T2.X as X2
  from Q1 T1,Q1 T2;
quit;

結果は




















となって、4掛ける4で16オブザベーションになります。
自己結合の場合、変数がどっちのテーブル由来(同じテーブルなのでどっちとかってのも変ですが)
か記述できなくなるので
Q1 T1のように「テーブル名 半角スペース 別名」として、Q1テーブルにT1という仮名を与えます。
Q1 as T1のようにas使ってもOKです



これだと、「い」「い」のように同じ値を2回使ったりします。

次に、同じものが2度現れない順列で
4P2を表現するなら、同じ値の出現を消せばいいわけなので

proc sql noprint;
 create table A2 as
  select T1.X as X1
        ,T2.X as X2
  from Q1 T1,Q1 T2
  where T1.X^=T2.X;
quit;

とすれば
















のように12オブザベーションになります。

ただ、これだと「い」「ろ」と「ろ」「い」のように、順番を並び変えただけの組み合わせ的には
同じものが含まれます。


そこで、 where T1.X^=T2.X;としているところをwhere T1.X<T2.X;としてしまいます。
文字列に不等号使うのに違和感を感じるかもしれませんが、文字の出現順で大小決まるだけなので数字と変わりません。
要するに、2パターンでてこられると困るので、不等号にしとけば絶対1パターンしかでないでしょって感覚なわけです。

proc sql noprint;
 create table A3 as
  select T1.X as X1
        ,T2.X as X2
  from Q1 T1,Q1 T2
  where T1.X<T2.X;
quit;


結果は










6オブザベーションで、正解です。

このあたりの話は以前SQL関連の書籍を紹介した中の
http://sas-tumesas.blogspot.jp/2013/10/sassql.html


達人に学ぶ SQL徹底指南書
 著者:ミック
 出版社:翔泳社 (2008/2/7)

を参考にしています。




0 件のコメント:

コメントを投稿