2016-11-10 24 views
1

私は別の分析の結果を更新したいデータセットを持っています。分析はループで行われます。ループの最後に、マスターデータセットが分析の値で更新されます。しかし、新しい値をマスターテーブルに挿入するのが難しいです。SAS:あるテーブルから別のテーブルに挿入

この例では、ループを削除しました。また、マスターデータセットを上書きするのではなく、コピーを作成します。

マスターデータセットには、値を挿入する必要がある行を特定するための2つの変数、つまりvar1var2があります。

data master; 
    input var1 $ var2 $; 

    datalines; 
    A A 
    A A 
    A B 
    A B 
    ; 
run; 

結果はループの一部なので、挿入は別々に実行する必要があります。つまり、分析の結果を単一の表に結合して1つのマージを実行することはできません。私はそれらを2つの別々のデータセットとしてここに与えました。

data first_insert; 
    input var1 $ var2 $ var3 $; 

    datalines; 
    A A C 
    ; 
run; 

data second_insert; 
    input var1 $ var2 $ var3 $; 

    datalines; 
    A B D 
    ; 
run; 

私の最初のアプローチは、MERGEステートメントを使用することです。しかし、これを行うと、すべてのデータがマスター表に書き込まれるわけではありません。

*****************; 
** Using Merge **; 
*****************; 

data master_merge_copy; 
    set master; 
run; 

data master_merge_copy; 
    merge master_merge_copy 
     first_insert 
     ; 
    by var1 var2; 
run; 

私は、それを期待しvar3var1 = A AND var2 = Aに値Cを配置するので、これはマージします。

Obs var1 var2 var3 
1  A  A  C 
2  A  A  C 
3  A  B 
4  A  B 

ただし、2番目のマージを実行すると、マージ基準に一致する最初の観測のみが書き込まれます。すべての観測にvar3 = Dと書く必要があります。var1 = A AND var2 = Bです。

data master_merge_copy; 
    merge master_merge_copy 
     second_insert 
     ; 
    by var1 var2; 
run; 

          Obs var1 var2 var3 
           1  A  A  C 
           2  A  A  C 
           3  A  B  D 
           4  A  B 

第2に、私はUPDATEステートメントを試してみます。

******************; 
** Using Update **; 
******************; 
data update_copy; 
    set master; 
run; 

data update_copy; 
    update update_copy 
     first_insert 
     ; 
    by var1 var2; 
run; 

ただし、BYグループ内で複数の観測があるとエラーが発生します。

WARNING: The MASTER data set contains more than one observation for a BY group. 
var1=A var2=A var3= FIRST.var1=0 LAST.var1=0 FIRST.var2=0 LAST.var2=1 _ERROR_=1 _N_=2 
WARNING: The MASTER data set contains more than one observation for a BY group. 
var1=A var2=B var3= FIRST.var1=0 LAST.var1=1 FIRST.var2=0 LAST.var2=1 _ERROR_=1 _N_=4 

結果のデータセットは、私が期待通りではありません。INSERTWHERE文でPROC SQLを使用したソリューションがあるかもしれないように思え

       Obs var1 var2 var3 

           1  A  A  C 
           2  A  A 
           3  A  B 
           4  A  B 

。しかし、挿入する値が別のテーブルに存在する場合、これをどうやって行うのかはわかりません。私が見つけることができるすべての例は、明示的に挿入される値を宣言します。たとえば、

proc sql; 
    update sql.newcountries 
     set population=population*1.05 
     where name like 'B%'; 
quit; 

助言してください。

+0

ほとんどの人が「挿入」と呼んでいることを実際には行っていないので、私はここで用語として「挿入」を使用しないでください。 ITでの 'insert'は、通常、列を追加せず、列を追加することを指します。 – Joe

+0

わかりません。何をINSERTしたいのですか?あなたの分析の結果を保持する新しいテーブルを作っていませんか? – Tom

+0

@Tom s/insert/updateは、SASの用語に関連しています。 OPにはマスタテーブルがあり、そのテーブルを第3の変数で一度に少しずつ更新しています(おそらく、いくつかの分析のために他の変数にループされているため) – Joe

答えて

2

何も挿入しないでください。新しいレコードを生成し、生成した新しい結果ファイルに追加します。まず、all_resultsが存在しないことを確認してください。その後、ループに現在の結果を追加します。だからあなたの例のデータは、これらのステップになります。

proc append base=all_results data=first_insert force; 
run; 
proc append base=all_results data=second_insert force; 
run; 

この表をマスター表とマージすることで、全体的な結果を作成できます。

data want ; 
    merge master all_results; 
    by var1 var2; 
run; 
0

LewisC_sasは、SASフォーラムで同様の質問に対する回答を提供できたようです。 SAS SQLの構文は奇妙なものですが、以下のように動作します。これはループの内部に実装されている場合、master_copyは一度だけコピーされていることを確認すること

data master; 
    input var1 $ var2 $; 

    datalines; 
    A A 
    A A 
    A B 
    A B 
    ; 
run; 

data first_insert; 
    input var1 $ var2 $ var3 $; 

    datalines; 
    A A C 
    ; 
run; 

data second_insert; 
    input var1 $ var2 $ var3 $; 

    datalines; 
    A B D 
    ; 
run; 

data master_copy; 
    set master; 
    length var3 $ 8.; 
run; 

proc sql; 
    update master_copy A 
    set var3 = (select var3 
    from first_insert 
    where A.var2 = var2) 
    where var2 in (select var2 
    from first_insert); 
    ; 
quit; 

proc sql; 
    update master_copy A 
    set var3 = (select var3 
    from second_insert 
    where A.var2 = var2) 
    where var2 in (select var2 
    from second_insert); 
    ; 
quit; 

は注意!

+0

これはかなり標準的なSQL構文なので、SAS SQL特有のものはありません。 – Joe

0

私はこれを書くためにかなり迷惑なので、このためにSQLを使用するのは好きではありません。私はまた、データ・ステップ・マージ技術(これには存在する)を使用するのは好きではない。

データ・ステップ・ハッシュは、この種のことに関して私の意見では最高です。もちろん

data want; 
    if 0 then set first_insert; 
    if _n_=1 then do; 
    declare hash f(dataset:'first_insert'); 
    f.defineKey('var1','var2'); 
    f.defineData('var3'); 
    f.defineDone(); 
    end; 
    call missing(of _all_); *prevents us from getting bit by the automatic RETAIN if `var3` is not on the master dataset; 
    set master; 
    rc = f.find(); 

run; 

、私は本当の最良の答えは、あなたができる場合は、最後にあなたの変更のすべてを保存し、それらを追加することですが、時にはそれが何らかの理由で実行可能ではないと思います。

関連する問題