2017-12-12 9 views
1

私は連続した逓減基準で12の月次データを1つのテーブルに結合しようとしています。毎月のデータ結合では、減少するシーケンスが表示されます。しかし、私はこれを実行するために複数のマクロを開発するロジックを考え出すのに苦労しています。 月はYYYYMM形式です。テーブルYYYYMMMため複数のループを持つSQLシーケンシャル月マクロ

コード `

PROC SQL; 
     CREATE TABLE WANT_YYYYMM AS /* I want the tables on monthly but incremental sequence basis. 
For e.g monthly data for 201612 will join with 201701,201702....201711.... 
monthly data for 201701 will join with 201702,201703....201711 and so on.*/ 
     SELECT (COUNT(A.canc_accts)) AS canc_accts_n, 
       (COUNT(A.canc_accts)) AS canc_accts_n+1, 
       (COUNT(A.canc_accts)) AS canc_accts_n+2, 
       ........ 
       (COUNT(A.canc_accts)) AS canc_accts_n+11   

    FROM HAVEDATA_YYYYMM A 
    LEFT JOIN HAVE_DATA_YYYYMM+1 B ON (A.ACCT_NO= B.ACCT_NO) 
    LEFT JOIN HAVE_DATA_YYYYMM+2 C ON (A.ACCT_NO= B.ACCT_NO) 
    LEFT JOIN HAVE_DATA_YYYYMM+3 D ON (A.ACCT_NO= B.ACCT_NO) 
    ........ 
    LEFT JOIN HAVE_DATA_YYYYMM+11 G ON (A.ACCT_NO= B.ACCT_NO) 
    GROUP BY A.Fees; 
    QUIT; 

` データは、月のマクロループとcanc_n変数を実行する上でいくつかの助けが必要この

  canc_n canc_n+1 canc_n+2...... canc_n+10 canc_n+11 

201612  200  225  250    325  350 
201701  222  240  277    312  - 
201702  210  232  234     - 
. 
. 
201711  200  -   - 

のようになります。これを構築するために複数のマクロやロジックを構築する上での助けに感謝します。

+1

なぜSQLでデータではないのですか? – Tom

+0

なぜあなたは同じことを数えていますか? COUNT(B ....)、COUNT(C ....)か? – Tom

+1

実際には、異なる* YYYYMM *接尾辞を持つ複数のデータセットがありますか?または、* YYYYMM *の1つのデータセットにフィールドがあります。後者の場合と同様に、SQLは宣言型言語であるため、テーブル名のような識別子の名前に関する論理を、含まれているフィールド内のデータだけで判断することはできません。 – Parfait

答えて

0

マクロで簡単にできます。文字列のような日付を生成しやすくするために、intnx()のような日付操作関数を使うことができます。

%macro codegen(yymm); 
%local month i ; 
%let month=%sysfunc(inputn(&yymm.01,yymmdd8)); 
PROC SQL; 
CREATE TABLE WANT_%sysfunc(intnx(month,&month,0),yymmn6) AS 
    SELECT COUNT(A.canc_accts) AS canc_accts_0 
%do i=1 %to 12 ; 
    ,COUNT(x&i..canc_accts) AS canc_accts_&i 
%end; 
    FROM HAVE_DATA_%sysfunc(intnx(month,&month,0),yymmn6) A 
%do i=1 %to 12 ; 
    LEFT JOIN HAVE_DATA_%sysfunc(intnx(month,&month,&i),yymmn6) x&i 
    ON (A.ACCT_NO= x&i..ACCT_NO) 
%end; 
    GROUP BY A.Fees 
; 
QUIT; 
%mend codegen ; 

私は値201605とそのマクロを呼び出すのであれば、それは、このSQLクエリを生成します。

CREATE TABLE WANT_201605 AS 
SELECT 
    COUNT(A.canc_accts) AS canc_accts_0 
,COUNT(x1.canc_accts) AS canc_accts_1 
,COUNT(x2.canc_accts) AS canc_accts_2 
,COUNT(x3.canc_accts) AS canc_accts_3 
,COUNT(x4.canc_accts) AS canc_accts_4 
,COUNT(x5.canc_accts) AS canc_accts_5 
,COUNT(x6.canc_accts) AS canc_accts_6 
,COUNT(x7.canc_accts) AS canc_accts_7 
,COUNT(x8.canc_accts) AS canc_accts_8 
,COUNT(x9.canc_accts) AS canc_accts_9 
,COUNT(x10.canc_accts) AS canc_accts_10 
,COUNT(x11.canc_accts) AS canc_accts_11 
,COUNT(x12.canc_accts) AS canc_accts_12 
FROM HAVE_DATA_201605 A 
LEFT JOIN HAVE_DATA_201606 x1 ON (A.ACCT_NO= x1.ACCT_NO) 
LEFT JOIN HAVE_DATA_201607 x2 ON (A.ACCT_NO= x2.ACCT_NO) 
LEFT JOIN HAVE_DATA_201608 x3 ON (A.ACCT_NO= x3.ACCT_NO) 
LEFT JOIN HAVE_DATA_201609 x4 ON (A.ACCT_NO= x4.ACCT_NO) 
LEFT JOIN HAVE_DATA_201610 x5 ON (A.ACCT_NO= x5.ACCT_NO) 
LEFT JOIN HAVE_DATA_201611 x6 ON (A.ACCT_NO= x6.ACCT_NO) 
LEFT JOIN HAVE_DATA_201612 x7 ON (A.ACCT_NO= x7.ACCT_NO) 
LEFT JOIN HAVE_DATA_201701 x8 ON (A.ACCT_NO= x8.ACCT_NO) 
LEFT JOIN HAVE_DATA_201702 x9 ON (A.ACCT_NO= x9.ACCT_NO) 
LEFT JOIN HAVE_DATA_201703 x10 ON (A.ACCT_NO= x10.ACCT_NO) 
LEFT JOIN HAVE_DATA_201704 x11 ON (A.ACCT_NO= x11.ACCT_NO) 
LEFT JOIN HAVE_DATA_201705 x12 ON (A.ACCT_NO= x12.ACCT_NO) 
GROUP BY A.Fees 
; 
+0

トムありがとう。これは本当に役に立ちます。私はあなたのコードに基づいて別の主要な質問があります。上記の例のように、201605のテーブルですが、その後の月(201606,201607など)に実行する必要があります。 – user9058407

+0

マクロを実行するには、次のようにします。そのパラメータの名前と値を指定します。マクロへの複数の呼び出しを生成する方法はたくさんあります。あなたは自分で電話を繰り返すことができます。 '%codegen(201605); %codegen(201606);または、このマクロへの複数の呼び出しを生成する別のマクロを作成します。あるいは、 'call execute()'を使ってデータステップから呼び出しを生成します。または、マクロを変更して別のループを追加し、複数のデータセットを作成することもできます。 – Tom

0

マクロを使用してすべてのデータをスタックします。スタッカーは新しいカテゴリ変数 "source"を追加します。次に、スタック上でカウント/ピボット変換を行います。

data have_201701; 
    account = 1; 
    fee = 'revert'; 
run; 

%macro stack (out=, base=, from=, months=12); 
    %local i ym ymf; 

    %let ym = %sysfunc(inputn(&from,yymmn6)); 

    data &out/view=&out; 
     set 
     %do i = 1 %to &months; 

      %let ymf = %sysfunc(putn(&ym,yymmn6)); 
      &base.&ymf 

      %let ym = %sysfunc(intnx(month,&ym,1)); 

     %end;    
     indsname = _source_ 
     ; 
     source = _source_; 
    run; 
%mend; 

options nodsnferr; * do not cause an error if the there is a request for a data set that is not found; 

options mprint; * logging purposes only; 
%stack (out=tall, base=have_, from=201612); 
options nomprint; 

* Now deal with one or two data transformation steps based on "tall" and new categorical variable "source" ; 

SQL + TRANPOSE、TABULATE、REPORT、HASH、またはARRAYでピボットできます。

カウントの要件を示すために、特にアカウントやグループ別に料金を支払って表示し、それらの機能を必要な出力に維持しないことを示すためには、元の質問が十分ではありませんでした。

関連する問題