ラベル select into: の投稿を表示しています。 すべての投稿を表示
ラベル select into: の投稿を表示しています。 すべての投稿を表示

SQLでマクロ変数に値を格納する into: separated by

SQLでマクロ変数に値を格納する方法についてご質問いただきましたので、あまり詳しくなくて自信がないですが紹介します。

SELECT INTO:を利用します。

proc sql noprint;
select count(*) into:obs
from DS;
quit;

などでデータセットのオブザベーション数をobsというマクロ変数に格納できます。

他に例えば

data Q1;
X='い';Y='A';Z=1;output;
X='ろ';Y='B';Z=2;output;
X='は';Y='C';Z=3;output;
run;







のようなデータセットがあった場合


proc sql noprint;
 select X,Y,Z
 into  :MX1-:MX3
      ,:MY1-:MY3
      ,:MZ1-:MZ3
 from Q1
 ;
quit;

のようにかけば、マクロ変数MX1にXの一つ目の値、MX2に二つ目の値、以下、同Y同Zに同じように格納できます。

%put &MX1
     &MX2
     &MX3
     &MY1
     &MY2
     &MY3
     &MZ1
     &MZ2
     &MZ3
;

するとログにでるのは




です。


データセットのオブザベーション数が可変だけども、どれくらいになるかある程度わかっていれば

proc sql noprint;
 select X,Y,Z
 into  :MX1-:MX999
      ,:MY1-:MY999
      ,:MZ1-:MZ999
 from Q1
 ;
quit;

と大雑把な方法ですが、大きくとっておけば、オブザベーションがない場合も
よけいなマクロ変数は作成されないので、使えます。


あと、以下のように書くと

proc sql noprint;
 select X,Y,Z
 into  :MXALL separated by '、'
      ,:MYALL separated by '、'
      ,:MZALL separated by '、'
 from Q1
 ;
quit;


%put &MXALL
     &MYALL
     &MZALL
;

ログは





のように、データをseparated by で指定した区切り文字で連結したものを一つのマクロ変数に
格納できるので、マクロのパラメータや関数の引数に渡したい値を作る時などに重宝します。

他にselect into:について技をお持ちの方がいらっしゃれば、むしろ勉強させていただきたいです。
call symputはデータステップの中でやるので、可変的にマクロ変数を作るうえで凄いやりやすい
のですが、SQLでもできないでしょうか、、。

多分、色々できると思うのですが、、いっつも、とりあえずわかる方法でやってしまって、なかなか新手開拓ができてないです。









Create tableだけがSQLプロシジャでデータセットを作る方法ではないという話

今適当な、データセットがあったとします。

data Q1;
X=1;Y=2;output;
X=3;Y=4;output;
X=5;Y=6;output;
run;

そこで以下のSQLを実行すれば

proc sql noprint;

 create table A1 as
  select X
  from Q1
  where X<2;

 create table A2 as
  select X
  from Q1
  where X>2;

 create table A3 as
  select Y
  from Q1;

quit;

データセットA1,A2,A3が作成されます。

SQLプロシジャ内でcreate table データセット名 as 以下クエリを書けば
結果がデータセットになります。

SQLプロシジャでデータセットを作成するには上記のやり方しかないと思われている方も多いですが、そんなことはないです。
抜け道のようですが、SQLプロシジャはあくまでSASのプロシジャで、アウトプットを伴うプロシジャです。であれば、

ods listing close;
proc sql;
ods output SQL_Results=A1;
  select X
  from Q1
  where X<2;

ods output SQL_Results=A2;
  select X
  from Q1
  where X>2;

 ods output SQL_Results=A3;
  select Y
  from Q1
;
quit;

当然、ODSの対象であり、ODSの対象であれば ods outputでデータセットにできるということです。
上記のコードで同じ結果を得ることができます。

これをどう活かすかを考えます。

例えばSASのデータステップでは

data A4 A5 A6;
 set Q1;
 if X=1 then output A4;
 if X=2 then output A5;
 if X=3 then output A6;
run;

のように一回のデータステップで、複数のデータセットを作れます。
しかし、create table文では、1回で同様の操作はできません(多分、、)

ですがODSを利用すれば

proc sql;
ods output 
  SQL_Results=A4(where=(X=1))
  SQL_Results=A5(where=(X=3))
  SQL_Results=A6(where=(X=5))
;
  select X
  from Q1
;
quit;

このように実現可能です。

また、データステップでは、call symput等で、データセットを作成すると同時に
何らかの値をマクロ変数に格納する処理も同時に行えます。

ですがSQLで同様のことを1文ではできません。

がODSを利用すれば

proc sql;
ods output SQL_Results=A7;
 select X into:MX
 from Q1
 where Y=4;
quit;


のように、非常に幅の広いことができるようになります。
邪道といえば邪道かもしれませんが、せっかく、SASでSQLを使っているので
SASから利用できる部分はガンガン使っちゃっていいんじゃないでしょうか?
(DB内部やほかのシステムににSQL文を移植したりする予定がなければですが)