sas将数据追加到表中,并在结果表上增加一个标志

aoyhnmkz  于 2021-08-09  发布在  Java
关注(0)|答案(5)|浏览(662)

我在sas上有两个表“table\u a”和“table\u a\u archive”,作为etl过程的一部分,“table\u a”是每天创建的,数据应该归档在“table\u a\u archive”上。当数据存档在“表\存档”时,将创建/更新一个标记“dt\标记”。
在第一天,这就是table的样子

"Table_A"
 | ID  | Load_Date
 ------ -------------
 | 100 | 01JUN2020:12:13:56

 "Table_A_Archive"
  | ID  | Load_Date           | DT_FLAG
  ------ --------------------- ---------
  | 100 | 01JUN2020:12:13:56  | 1

第2天

"Table_A"
 | ID  | Load_Date
 ------ ------------
 | 101 | 02JUN2020:12:13:56

 "Table_A_Archive"
 | ID  | Load_Date           | DT_FLAG
 ------ --------------------- ---------
 | 100 | 01JUN2020:12:13:56  | 2
 | 101 | 02JUN2020:12:13:56  | 1

加载新数据时,dtu标志应为1,旧记录dtu标志应递增1。装货日期是关键。我已经写了一个sas代码,但它似乎有点混乱,有人能帮我一个sas数据步骤吗

%macro Cntl_archive(table_name=,arch_table_name=);
 %GLOBAL WRK;

 %if %sysfunc(exist(&arch_table_name.))  %then %do;

 proc append base=&arch_table_name. data=&table_name. force;
 run;

 proc sql;
 Create table TEMP as 
 Select distinct Load_Date,Load_Date as WRK from &arch_table_name.
 order by Load_Date desc
 ;quit;

 proc rank data=TEMP descending out=TEMP;
 var WRK;
 ranks count;
 run;

 data &arch_table_name. (drop=DT_FLAG);
 set    &arch_table_name.;
 run;

 proc sql;
 Create table &arch_table_name. as
 Select T0.*,T1.count as DT_FLAG from &arch_table_name. T0
 inner join TEMP T1 on T0.Load_Date=T1.Load_Date
 ;quit
 %end;
 %else %do;

data &arch_table_name.;
set &table_name.;
DT_FLAG= 1; 
IS_ACTIVE='';
run;
%end;
%mend Cntl_archive;
f45qwnt8

f45qwnt81#

我想你也应该这样做 merge 声明:

%if %sysfunc(exist(Table_A_Archive)) = 0 %then %do;
  data Table_A_Archive;
    set Table_A;
  run;
%end;

data Table_A_Archive;
  merge Table_A_Archive(in=ALL) Table_A;
  by ID;

  if ALL then DT_FLAG = sum(DT_FLAG,1);
  else DT_FLAG = 1;
run;

考虑到你可能希望这项日常工作尽可能快,我建议使用 update 或者 modify 要替换的语句 merge :

%if %sysfunc(exist(Table_A_Archive)) = 0 %then %do;
  data Table_A_Archive;
    set Table_A;
  run;
%end;

data Table_A_Archive;
  update Table_A_Archive Table_A;
  by ID;

  if _iorc_ = %sysrc(_sok) then DT_FLAG = sum(DT_FLAG,1);
run;

它更高效,因为它可以更新(或修改)数据,而无需创建数据集的副本。

arknldoa

arknldoa2#

下面是一个使用 MODIFY 语句更新现有观测值中的dt_标志值并附加新值。
首先让我们创建一个初始的a,并使用它创建一个带有额外变量的空a\u存档(注意:我重命名了timestamp变量,以避免由于名为“date”的变量具有datetime值而不是date值而引起的混淆。)

data a ;
  input id load_dt :datetime.;
  format load_dt datetime19.;
cards;
100 01JUN2020:12:13:56
;

data a_archive;
  stop;
  set a ;
  dt_flag=0;
run;

现在让我们将一个附加到一个\u存档中。

data a_archive;
  do while(not eof1);
    modify a_archive end=eof1;
    dt_flag=sum(dt_flag,1);
    replace;
  end;
  do until(eof2);
    set a end=eof2;
    dt_flag=1;
    output;
  end;
run;

现在您可以创建一个新版本的,并重新运行相同的数据步骤来附加它。

data a ;
  input id load_dt :datetime.;
  format load_dt datetime19.;
cards;
101 02JUN2020:12:13:56
;

data a_archive;
  do while(not eof1);
    modify a_archive end=eof1;
    dt_flag=sum(dt_flag,1);
    replace;
  end;
  do until(eof2);
    set a end=eof2;
    dt_flag=1;
    output;
  end;
run;

结果:

Obs     id                load_dt  dt_flag

 1     100     01JUN2020:12:13:56       2
 2     101     02JUN2020:12:13:56       1
goucqfw6

goucqfw63#

使用 Proc APPEND 和计算 DT_FLAG 在需要的时候飞行。除了向档案中添加记录外,无需对档案进行任何处理。
正在运行的将是数据步骤视图。
例子:
例子 want 数据集位于 WORK. 但会是一些 PERM. 在你的真实世界里。


* simulate a clean start and some ETL activity with APPEND archiving;

proc delete data=want;
proc delete data=want_archive;

* DAY 1,  load #1;

data DAILY_ETL;
  ID = 100;   load_date = today()-100;   format load_date yymmdd10.;
run;
data want; 
  set DAILY_ETL; 
run;
proc append base=want_archive data=want;
run;

* DAY 2, load #2;

data DAILY_ETL;
  ID = 100;   load_date = today()-99;   format load_date yymmdd10.;
run;
data want; 
  set DAILY_ETL; 
run;
proc append base=want_archive data=want;
run;

* DAY 4, load #3;

data DAILY_ETL;
  ID = 100;   load_date = today()-97;   format load_date yymmdd10.;
run;
data want; 
  set DAILY_ETL; 
run;
proc append base=want_archive data=want;
run;

和观看


* view for on-the-fly DT_FLAG (do once);

data want_archive_v;
  set want_archive nobs=N;
  dt_flag = N - _N_ + 1;
run;

dm 'viewtable want_archive_v';

qxsslcnc

qxsslcnc4#

再考虑一下 proc sql 与计数相关的子查询。不幸的是,sas不允许用值更新表本身,因此使用临时表副本。下面假设id每天递增。

proc sql;
    insert into Table_A_Archive (ID, Load_Date)
    select ID, Load_Date
    from Table_A;

    create table temp as
    select ID, Load_Date from Table_A_Archive;

    update Table_A_Archive t
    set DT_Flag = (select count(*) 
                   from temp sub
                   where t.ID <= sub.ID 
                   and   t.Load_Date = sub.Load_Date);

    drop table temp;
quit;
8dtrkrch

8dtrkrch5#

我试着用这种方法解决它。

%macro Cntl_archive(table_name=,arch_table_name=);

%if %sysfunc(exist(&arch_table_name.))  %then %do;

data Data_append;
set &table_name.;
if _n_ = 1
then do;
  set &arch_table_name.(keep=dt_flag) point=nobs nobs=nobs;
dt_flag + 1;
end;
run;

proc append base=&arch_table_name. data=Data_append force;
run;

%end;
%else %do;

data &arch_table_name.;
set &table_name.;
DT_FLAG= 1; 
IS_ACTIVE='';
run;
%end;
%mend Cntl_archive;

相关问题