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

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

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

  1. "Table_A"
  2. | ID | Load_Date
  3. ------ -------------
  4. | 100 | 01JUN2020:12:13:56
  5. "Table_A_Archive"
  6. | ID | Load_Date | DT_FLAG
  7. ------ --------------------- ---------
  8. | 100 | 01JUN2020:12:13:56 | 1

第2天

  1. "Table_A"
  2. | ID | Load_Date
  3. ------ ------------
  4. | 101 | 02JUN2020:12:13:56
  5. "Table_A_Archive"
  6. | ID | Load_Date | DT_FLAG
  7. ------ --------------------- ---------
  8. | 100 | 01JUN2020:12:13:56 | 2
  9. | 101 | 02JUN2020:12:13:56 | 1

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

  1. %macro Cntl_archive(table_name=,arch_table_name=);
  2. %GLOBAL WRK;
  3. %if %sysfunc(exist(&arch_table_name.)) %then %do;
  4. proc append base=&arch_table_name. data=&table_name. force;
  5. run;
  6. proc sql;
  7. Create table TEMP as
  8. Select distinct Load_Date,Load_Date as WRK from &arch_table_name.
  9. order by Load_Date desc
  10. ;quit;
  11. proc rank data=TEMP descending out=TEMP;
  12. var WRK;
  13. ranks count;
  14. run;
  15. data &arch_table_name. (drop=DT_FLAG);
  16. set &arch_table_name.;
  17. run;
  18. proc sql;
  19. Create table &arch_table_name. as
  20. Select T0.*,T1.count as DT_FLAG from &arch_table_name. T0
  21. inner join TEMP T1 on T0.Load_Date=T1.Load_Date
  22. ;quit
  23. %end;
  24. %else %do;
  25. data &arch_table_name.;
  26. set &table_name.;
  27. DT_FLAG= 1;
  28. IS_ACTIVE='';
  29. run;
  30. %end;
  31. %mend Cntl_archive;
f45qwnt8

f45qwnt81#

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

  1. %if %sysfunc(exist(Table_A_Archive)) = 0 %then %do;
  2. data Table_A_Archive;
  3. set Table_A;
  4. run;
  5. %end;
  6. data Table_A_Archive;
  7. merge Table_A_Archive(in=ALL) Table_A;
  8. by ID;
  9. if ALL then DT_FLAG = sum(DT_FLAG,1);
  10. else DT_FLAG = 1;
  11. run;

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

  1. %if %sysfunc(exist(Table_A_Archive)) = 0 %then %do;
  2. data Table_A_Archive;
  3. set Table_A;
  4. run;
  5. %end;
  6. data Table_A_Archive;
  7. update Table_A_Archive Table_A;
  8. by ID;
  9. if _iorc_ = %sysrc(_sok) then DT_FLAG = sum(DT_FLAG,1);
  10. run;

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

展开查看全部
arknldoa

arknldoa2#

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

  1. data a ;
  2. input id load_dt :datetime.;
  3. format load_dt datetime19.;
  4. cards;
  5. 100 01JUN2020:12:13:56
  6. ;
  7. data a_archive;
  8. stop;
  9. set a ;
  10. dt_flag=0;
  11. run;

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

  1. data a_archive;
  2. do while(not eof1);
  3. modify a_archive end=eof1;
  4. dt_flag=sum(dt_flag,1);
  5. replace;
  6. end;
  7. do until(eof2);
  8. set a end=eof2;
  9. dt_flag=1;
  10. output;
  11. end;
  12. run;

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

  1. data a ;
  2. input id load_dt :datetime.;
  3. format load_dt datetime19.;
  4. cards;
  5. 101 02JUN2020:12:13:56
  6. ;
  7. data a_archive;
  8. do while(not eof1);
  9. modify a_archive end=eof1;
  10. dt_flag=sum(dt_flag,1);
  11. replace;
  12. end;
  13. do until(eof2);
  14. set a end=eof2;
  15. dt_flag=1;
  16. output;
  17. end;
  18. run;

结果:

  1. Obs id load_dt dt_flag
  2. 1 100 01JUN2020:12:13:56 2
  3. 2 101 02JUN2020:12:13:56 1
展开查看全部
goucqfw6

goucqfw63#

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

  1. * simulate a clean start and some ETL activity with APPEND archiving;
  2. proc delete data=want;
  3. proc delete data=want_archive;
  4. * DAY 1, load #1;
  5. data DAILY_ETL;
  6. ID = 100; load_date = today()-100; format load_date yymmdd10.;
  7. run;
  8. data want;
  9. set DAILY_ETL;
  10. run;
  11. proc append base=want_archive data=want;
  12. run;
  13. * DAY 2, load #2;
  14. data DAILY_ETL;
  15. ID = 100; load_date = today()-99; format load_date yymmdd10.;
  16. run;
  17. data want;
  18. set DAILY_ETL;
  19. run;
  20. proc append base=want_archive data=want;
  21. run;
  22. * DAY 4, load #3;
  23. data DAILY_ETL;
  24. ID = 100; load_date = today()-97; format load_date yymmdd10.;
  25. run;
  26. data want;
  27. set DAILY_ETL;
  28. run;
  29. proc append base=want_archive data=want;
  30. run;

和观看

  1. * view for on-the-fly DT_FLAG (do once);
  2. data want_archive_v;
  3. set want_archive nobs=N;
  4. dt_flag = N - _N_ + 1;
  5. run;
  6. dm 'viewtable want_archive_v';

展开查看全部
qxsslcnc

qxsslcnc4#

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

  1. proc sql;
  2. insert into Table_A_Archive (ID, Load_Date)
  3. select ID, Load_Date
  4. from Table_A;
  5. create table temp as
  6. select ID, Load_Date from Table_A_Archive;
  7. update Table_A_Archive t
  8. set DT_Flag = (select count(*)
  9. from temp sub
  10. where t.ID <= sub.ID
  11. and t.Load_Date = sub.Load_Date);
  12. drop table temp;
  13. quit;
展开查看全部
8dtrkrch

8dtrkrch5#

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

  1. %macro Cntl_archive(table_name=,arch_table_name=);
  2. %if %sysfunc(exist(&arch_table_name.)) %then %do;
  3. data Data_append;
  4. set &table_name.;
  5. if _n_ = 1
  6. then do;
  7. set &arch_table_name.(keep=dt_flag) point=nobs nobs=nobs;
  8. dt_flag + 1;
  9. end;
  10. run;
  11. proc append base=&arch_table_name. data=Data_append force;
  12. run;
  13. %end;
  14. %else %do;
  15. data &arch_table_name.;
  16. set &table_name.;
  17. DT_FLAG= 1;
  18. IS_ACTIVE='';
  19. run;
  20. %end;
  21. %mend Cntl_archive;
展开查看全部

相关问题