我希望有人能够帮助我。我有一些相当冗长的SQL代码,它提取了一些信息,包括销售和网络数据。我需要在多个城市运行它。但是,不是多次重新运行代码,而是每次手动更改城市。我想知道我是否可以使用宏,以便代码只写一次,但是城市是某种类型的宏变量,当代码运行时,它会读出一个感兴趣的城市表,输出将是一个表对于每一个。
为了把事情放到上下文中,下面是代码的摘录,您可以在其中看到变量' City'这是'伦敦'对于这个例子。
rsubmit;
proc sql;
create table help as
select distinct a.customer_id, max(a.level) as level, a.london
from (
select distinct customer_id, max(SESSION_DT) as session_dt format date9., TXT,
case when TXT in ('Gold') then 1
when TXT in ('Silver') then 2
when TXT in ('Bronze') then 3
else 4 end as level,
case when customer_id is not null then "3" else '' end as London
from search_data
where CITY in ('London') and TXT is not null
group by 1) a
group by 1;
quit;
endrsubmit;
答案 0 :(得分:2)
您确定可以将城市名称字符串放入宏变量中,然后将其解析出来,但是,它将具有64K字节的长度限制以及宏编程的复杂性。以下是我在这种情况下会做的事情: 1.将主代码放入宏中 2.将所有城市名称放入SAS表中。 3.使用CALL EXECUTE()动态调用宏。
%macro test(city=London);
rsubmit;
proc sql;
create table help as
select distinct a.customer_id, max(a.level) as level, a.london
from (
select distinct customer_id, max(SESSION_DT) as session_dt format date9., TXT,
case when TXT in ('Gold') then 1
when TXT in ('Silver') then 2
when TXT in ('Bronze') then 3
else 4 end as level,
case when customer_id is not null then "3" else '' end as London
from search_data
where CITY eq "&city." and TXT is not null
group by 1) a
group by 1;
quit;
endrsubmit;
%mend;
data _null_;
set cities; /*this is where you store city names in a variable named CITY, one per row*/
call execute ('%test (city= '||city ||')' );
run;
答案 1 :(得分:1)
如果我正确理解您的代码,您可以在一个SQL步骤中完成所需的操作,而不是尝试使用宏遍历城市:
proc format;
value $level.
'Gold' = 1
'Silver' = 2
'Bronze' = 3
other = 4
;
value customer_city
. = ''
other = 3
;
run;
proc sql;
create table help as
select
distinct customer_id
, city
, max(session_id) as session_id
, max(put(TXT, $level.)) as level
, put(customer_id, customer_city.) as customer_city
from search_data
where TXT is not null
group by customer_id, city
;
quit;
这里" customer_city"取而代之的是你所拥有的" a.London"," a.Tokyo"等
没有" search_data"的描述以及你想要的输出的一个例子,我无法自信地说这段代码将完全符合您的要求 - 它甚至可能会出现一些错误。但是你应该能够适当地修改它并一步完成所有的摘要。
在您的方法中,SQL循环遍历search_data一次,然后再循环遍历聚合数据。那么你将不得不为你拥有的每个城市做到这一点。换句话说,您扫描数据集的次数约为2 *城市数量。如果search_data很大,这将比在一个SQL步骤中执行此操作慢得多。
如果你真的需要为每个城市提供一个单独的表,那么你可以用这个宏拆分它们:
%macro subset_city(data, city);
data &city._table(rename=(customer_city=&city.));
set &data.;
where city = &city.;
run;
%mend subset_city;
data _null_;
set list_of_cities;
call execute ('%subset_cities(data =help, city= '||city ||')');
run;