#sql #sas
#sql #sas
Вопрос:
предположим, у меня есть большой список таблиц, скажем :
%let y = jan feb mar apr may jun jul aug sep oct nov dec
все эти таблицы имеют одинаковые имена столбцов и количество столбцов, я хочу сложить все эти таблицы одну под другой в одном наборе данных
я попытался создать макрос для этого (потому что у меня есть несколько других списков, которые больше этого, но до сих пор мне это не удавалось
%let y = jan feb mar apr may jun jul aug sep oct nov dec
%macro con_tabs(in);
%local i s;
%do i=1 %to %sysfunc(countw(amp;in.,%str( )));
%let samp;i.=%scan(amp;in.,amp;i.,%str( ));
proc sql;
create table tabamp;i. as
select * from amp;amp;samp;i...a union all
select * from amp;amp;samp;(i 1)...b;
quit;
%end;
%mend con_tabs;
Комментарии:
1. Есть ли какая-либо причина, по которой вы пытаетесь использовать SQL вместо обычного кода SAS?
2. нет, просто я не знал, как выполнить это, используя обычный код sas ( и я думал, что это будет проще с использованием proc sql)
3. Код SQL редко бывает проще. Иногда это лучше, например, для соединений «многие ко многим» или соединений, которые не являются точными совпадениями ключевых переменных.
Ответ №1:
Если вы хотите продолжать использовать SQL для этой задачи, вам потребуется правильно сконструировать инструкцию SQL для многих таблиц UNION ALL
.
Не следует итеративно «добавлять» одну таблицу за раз, используя одно ОБЪЕДИНЕНИЕ ВСЕГО стека и следующей таблицы. Вместо этого выполните все стекирование в одном операторе SQL.
Пример:
data t1 t2 t3 t4 t5 t6;
retain x 1;
run;
%macro sql_stack(table_list=, out=);
%local index table;
proc sql;
%do index = 1 %to %sysfunc(countw(amp;table_list));
%if amp;index = 1 %then
CREATE TABLE amp;OUT AS /* sql code gen */
;
%else
UNION ALL /* sql code gen */
;
%let table = %scan(amp;table_list, amp;index);
SELECT
"amp;table" as source,
*
FROM amp;table /* sql code gen */
%end;
; /* end code gen statement */
QUIT;
%mend sql_stack;
%sql_stack(table_list=t1 t2 t3 t4 t5, out=want);
Будет ли код gen
CREATE TABLE want AS
SELECT "t1" as source, * FROM t1
UNION ALL SELECT "t2" as source, * FROM t2
UNION ALL SELECT "t3" as source, * FROM t3
UNION ALL SELECT "t4" as source, * FROM t4
UNION ALL SELECT "t5" as source, * FROM t5
;
QUIT;
Ответ №2:
Просто используйте шаг данных.
%let y = jan feb mar apr may jun jul aug sep oct nov dec ;
data want;
set amp;y ;
run;