具有多个循环的SQL-顺序月宏

时间:2017-12-12 17:12:05

标签: sql macros sas

我正在尝试按顺序拒绝将12个月度数据加入到单个表中。每月数据连接将查看下降的序列。但是,我正在努力想出一个逻辑来开发多个宏来运行它。 月份是YYYYMM格式。

代码 `

    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;

` 表YYYYMMM的数据应该如下所示

            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      -         -

在运行月份的宏循环和canc_n变量时需要一些帮助。任何帮助构建多个宏或任何逻辑来构建它将不胜感激。

2 个答案:

答案 0 :(得分: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 
;

答案 1 :(得分:0)

使用宏来堆叠所有数据。堆栈器将添加一个新的分类变量“source”。然后在堆栈上进行count / pivot变换。

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进行数据透视。

最初的问题不足以表明计数要求,特别是在显示按帐户和小组加费而不是在所需输出中维护这些功能时。