如果每天都需要从数据库或者数据仓库中获取数据,但是数据有可能未更新或者更新错误,就可以用以下的宏进行检查。
写出来运行了很久,目前看来效果不错,可以节约检查的时间。
运行结果如下:
| 数据集 | 最新数据 | 数据总数 | 总量差(与数据仓库) | 主键丢失 | 及时更新 | 数据连续 | 断点日期 | 间隔天数 | 标准差 | 最近一天数据 | 7天同比 |
| test | 2016/1/20 | 123456 | -1234 | 0 | 1 | 1 | 2016/1/20 | 1 | 0.1234 | 1234 | 0.1234% |
需要注意的是,每次成功运行,数据集的编号会自动增加(c1,c2,c3...),这个是比较适合调试完毕后进行批量执行的。
比如检查10个数据集,会自动生成c1-c10,用set语句连接起来就可以对更新的数据集做一个全面的检查了。
/*为批量执行检测,为检测结果数据集编号
初始化全局宏变量setn*/
%global setn;
%let setn=1;
/*
input=输入数据集
key=日期
start=自定义开始检测日期
source=数据库数据集位置*/
%macro dc2(input,key,start,source);
data a1;
set &input;
run;
%sort(a1,&key)
/*获取首尾变量
ps:获取的方法应该可以用系统宏变量之类的*/
data a2;
if 0 then set a1 nobs=a;
set a1;
if _n_=1 then call symput('first',&key);
if _n_=a then call symput('last',&key);
run;
/*统计日期丢失情况*/
data a3;
set a1;
where &key ne .;
run;
/*计算无缺失的天数*/
proc summary data=a3;
var &key;
output out=b1 n(&key)=nmis;
run;
/*把日期传递给宏变量*/
data _null_;
set b1;
call symput('nmis',nmis);
call symput('total_obs',_freq_);
run;
/*日期连续性检查*/
%dsort(a1 out=a4,&key)
data a4;
set a4;
if &key ge max(&start,&first);
run;
data a5;
retain comp;
set a4;
if _n_=1 then comp=&key+0;
gap=&key-comp;
comp=&key+0;
run;
%sort2(a5,gap,&key)
/*b2 gap最大或者日期最近*/
data b2;
set a5 nobs=a;
if _n_=a;
keep &key gap;
rename &key=cdate;
run;
data _null_;
set b2;
call symput('cdate',cdate);
call symput('gap',gap);
run;
/*与数据仓库/数据库 比较*/
proc sql;
create table b3 as
select count(*) as s_num from &source;
quit;
data _null_;
set b3;
call symput('s_num',s_num);
run;
/*标准差及7天同比*/
data a6;
set a1;
if &key ge today()-60;
if &key le today()-1;
run;
%grp(a6,a7,&key,recs)
data _null_;
set a7;
if &key eq today()-1 then call symput('last_rec',recs);
else call symput('last_rec',0);
if &key eq today()-8 then call symput('last_7rec',recs);
run;
proc summary data=a7;
var recs;
output out=b4 std(recs)=sr mean(recs)=mr;
run;
data _null_;
set b4;
call symput('sr',sr);
call symput('mr',mr);
run;
data _null_;
call symput('c',cats('c',"&setn"));
run;
data &c;
length setname $ 15;
retain setname last_date total_obs total_check mis
update consec cdate gap sigma last_rec l7_compare;
last_date=symget('last')+0;
total_obs=symget('total_obs')+0;
s_num=symget('s_num')+0;
cdate=symget('cdate')+0;
gap=symget('gap')+0;
nmis=symget('nmis')+0;
sr=symget('sr')+0;
mr=symget('mr')+0;
setname=symget('input');
last_rec=symget('last_rec')+0;
last_7rec=symget('last_7rec')+0;
total_check=total_obs-s_num;
mis=total_obs-nmis;
if gap eq 1 then consec=1;
else consec=0;
sigma=(last_rec-mr)/sr;
l7_compare=(last_rec-last_7rec)/last_7rec;
if today()-last_date le 1 then update=1;
else update=0;
drop s_num nmis mr sr last_7rec ;
format last_date yymmdd10. l7_compare percent7.2 cdate yymmdd10.
sigma 4.1;
label setname='数据集' last_date='最新数据' total_obs='数据总数'
total_check='总量差(与数据仓库)' mis='主键丢失' update='及时更新'
consec='数据连续'
cdate='断点日期' gap='间隔天数' sigma='标准差' last_rec='最近一天数据'
l7_compare='7天同比';
run;
data _null_;
call symput('setn',&setn+1);
run;
%mend;