循环遍历表并在SAS中加入它们

时间:2017-01-24 12:38:03

标签: loops sas union proc-sql

我无法解决一个问题。

我在一个SAS库中有未知数量的表。我想制作一个循环,通过它们和#34; UNION ALL"那些表。

预先检查表格,它们具有相同的结构。这些表包括历史数据,因此它应该是Union all。 我尝试了以下脚本,但它会搜索所有可能性,但不会执行UNION ALL。

我很感激任何想法来解决这个问题。

%macro union_tables(table_name, last_extract); 
 %do i=1 %to &last_extract.;
        select * from data.&table_name&i
        union all
 %end;
        select * from data.&table_name&i
%mend;

proc sql; 
create table Full_history as 
%union_tables(Table_,1216);
quit;

提前谢谢你。

5 个答案:

答案 0 :(得分:5)

也许您可以省去宏并使用SET语句。

data Many;
   set table_: open=defer;
   run;

如果表与变量和类型完全相同,Open = defer可以节省大量内存。

答案 1 :(得分:1)

您的宏正在查找名为table_1table_1216的表,并在找不到不存在的表时给出错误。您需要更改循环,以便它只尝试获取实际存在的表的并集。

答案 2 :(得分:1)

如果: A)所有文件名的总长度+其libname前缀+句点是< 32767;和 B)你的组成文件都在一个库中;和 C)您的文件都以'表_'

开头
data _null_;
length datasets $32767; *make sure this is long enough to hold all your dataset names + their libname prefix.  32767 is the max string length;
retain datasets;
set sashelp.vstable end=eof; *This system view holds all known datasets in all known libraries;
where upcase(libname)='DATA'; *The libname where you dsets live.  Use all uppercase;
if index(UPCASE(memname),'TABLE_') =1 /*Your code shows all datasets begin with 'Table_'*/ then
datasets=trim(datasets)||
 ' '||trim(libname)||
 '.'||trim(memname);
if eof then call symput('datasets',datasets);
run; 
%put &datasets; *print them to the log;

data all_the_datasets;
set &datasets;
run;

作为参考,我从Richardson& Sons的SUGI 29论文的第5页中解释了大部分内容。罗斯兰。

答案 3 :(得分:0)

无论您的数据集如何命名,只需在创建订单变量后将它们全部放入列表中并将它们组合在一起(将work.替换为您的库的名称):

/* put all dataset names into a dataset */
proc contents data = work._all_ noprint out=ds_names(keep=memname); run;

/* dedupe the dataset and create an order variable */
data ds_names1; set ds_names;
    by memname;
    if first.memname;
    order_var + 1;
run;

/* put the ordered datasets into a macro variable list */
proc sql noprint;
    select distinct(memname)
    into: ds_list separated by " "
    from ds_names1
    order by order_var;
quit;

%put &ds_list.;

/* append all the datasets together in order */
%macro append_instead_of_set(ds_list);
%do i=1 %to %sysfunc(countw(&ds_list.));
    %let ds = %scan(&ds_list.,&i.);
    proc append data = &ds. base=full force; run;
%end;
%mend;

%append_instead_of_set(&ds_list.);

答案 4 :(得分:0)

谢谢大家的回复。我几乎没有用到达到我需要的结果。

我想发布自己的结果,因为我使用了Amw 5G和Foxer用户的部分代码。

/* get list of the tables */ 

%MACRO SHOW_TABLES(libname, regex);
proc sql noprint;
select memname
into :list_tables separated by " "

from dictionary.tables
where libname="&libname." and upcase(memname) like upcase("%quote(%%)&&regex%")
order by memname;
quit;

%MEND;

%show_tables(DATA, Table_);

%put LIST OF TABLES: &list_tables.;

/* putting data sets together*/
DATA data.Full_history;
SET data.&list_tables.;
RUN;

这样,即使存在不同的结构,它也会将所有表格放在一起。因为表可以随时间变化(某些列可以删除或添加新列)。

对于proc append表应具有相同的结构。因此,在我的情况下,合理使用data set