SAS Macro 将根据日期标准合并 Municipal Proc SQL 语句
SAS Macro to Combine Municipal Proc SQL Statements Based on Date Criteria
我有一系列 proc sql 语句,可以提取活跃、不活跃和失效客户的数据。我最终得到 3 tables。
- *Customers_Active
- *Customers_InActive
- *Customers_Lapsed
活跃:0-1200 万购买者
不活跃:13-24 百万购买者,未购买 0-12 百万(活跃日期范围减去 12 个月)
已失效:25-36 百万购买者,未购买 0-24 百万(不活跃天数范围减去 24 个月)
同样,为了做到这一点,我有 3 个单独的 proc sql 语句,我从定义 6 个宏变量开始。
我想应用宏语言,这样我就可以只使用 1 个查询来生成 3 个 table。
%let actstart = '24Feb2013'd;
%let actend = '22Feb2014'd;
%let iactstart = '26Feb2012'd;
%let iactend= '23Feb2013'd;
%let lapstart = '27Feb2011'd;
%let lapend = '25Feb2012'd;*
这是三个陈述
/活跃Table/
proc sql;
create table Customers_Active as
select
household_id,
customer_id,
web_order_id,
transaction_date,
sku,
quantity,
original_price
from transaction_vw
where transaction_date >= &actstart and transaction_date <= &actend
order by customer_id;
quit;
/无效Table/
请注意,我没有引入已经在 Customers_Active
table 中的 customer_id。
proc sql;
create table Customers_Inactive as
select
household_id,
customer_id,
web_order_id,
transaction_date,
sku,
quantity,
original_price
from transaction_vw
where transaction_date >= & iactstart and transaction_date <= &iactend
and customer_id not in (select distinct customer_id from Customers_Active)
order by customer_id;
quit;
/已失效 Table/
请注意,我没有引入 Customers_Active 和 Customers_Inactive table 中不存在的 customer_id。
proc sql;
create table Customers_Lapsed as
select
household_id,
customer_id,
web_order_id,
transaction_date,
sku,
quantity,
original_price
from transaction_vw
where transaction_date >= & lapstart and transaction_date <= & lapend
and customer_id not in (select distinct customer_id from Customers_Active)
and customer_id not in (select distinct customer_id from Customers_Inactive)
order by customer_id;
quit;
回顾一下:最终结果是 3 tables。
- *Customers_Active
- *Customers_InActive
- *Customers_Lapsed
•我正在为所有三个 table 引入相同的变量
•只是日期范围发生了变化
•此外,我不想在 Customers_Inactive table 中包含 customer_id,它已经在 Customers_Active table 中
•和 customer_ids 在失效的 table 中已经在 Customer_Active 和 Customer_inactive tables
再次强调,因为我要提取相同的变量,所以我不想用三个单独的查询来完成这一个。
我会以不同的方式来做这件事。您可以通过几种方式完成,但也许一个 SQL 步骤和一个数据步骤是最简单的。
proc sql;
create table lookup_lastdate as
select customer_id as start, max(transaction_Date) as label,
'LASTDATEF' as fmtname
from transaction_vw
group by customer_id;
quit;
proc format cntlin=lookup_lastdate;
quit;
%let today=11JUN2015;
data customers_active customers_inactive customers_lapsed;
set transaction_vw;
years = intck('YEAR',put(customer_id,LASTDATEF.),"&today."d,'c');
if years < 1 then output customers_active;
else if years < 2 then output customers_inactive;
else if years < 3 then output customers_lapsed;
run;
intck
末尾带有 c
修饰符表示两个日期之间的周期数,因此 1 年表示介于 1 年和 1 年 364 天之间。
这样做的目的是使用更少的数据传递 - 所以,首先计算上次购买的时间,然后输出他们的数据。它在 DoW 循环中甚至可能比这更有效(它执行 1 次真实传递和 2 次虚拟传递,假设数据适合内存)。所以我们使用一种格式来把它拿出来(如果你更喜欢连接,你也可以连接表格,格式更快)。然后我们使用 intck
比较该日期以查看已经过去了多少年,并输出到适当的文件。
附带说明一下,SAS 中有一个偏好,即不放置 3 个这样的文件,而是放置 1 个文件,然后添加一个标志,指示它属于哪个组;然后使用 by
语句分别对每个组进行分析。这进一步简化了代码。为此,只需更改 if
语句以设置标志而不是输出 - 或者跳过 if
并直接分配年份计数。
我有一系列 proc sql 语句,可以提取活跃、不活跃和失效客户的数据。我最终得到 3 tables。
- *Customers_Active
- *Customers_InActive
- *Customers_Lapsed
活跃:0-1200 万购买者
不活跃:13-24 百万购买者,未购买 0-12 百万(活跃日期范围减去 12 个月)
已失效:25-36 百万购买者,未购买 0-24 百万(不活跃天数范围减去 24 个月)
同样,为了做到这一点,我有 3 个单独的 proc sql 语句,我从定义 6 个宏变量开始。
我想应用宏语言,这样我就可以只使用 1 个查询来生成 3 个 table。
%let actstart = '24Feb2013'd;
%let actend = '22Feb2014'd;
%let iactstart = '26Feb2012'd;
%let iactend= '23Feb2013'd;
%let lapstart = '27Feb2011'd;
%let lapend = '25Feb2012'd;*
这是三个陈述
/活跃Table/
proc sql;
create table Customers_Active as
select
household_id,
customer_id,
web_order_id,
transaction_date,
sku,
quantity,
original_price
from transaction_vw
where transaction_date >= &actstart and transaction_date <= &actend
order by customer_id;
quit;
/无效Table/
请注意,我没有引入已经在 Customers_Active
table 中的 customer_id。
proc sql;
create table Customers_Inactive as
select
household_id,
customer_id,
web_order_id,
transaction_date,
sku,
quantity,
original_price
from transaction_vw
where transaction_date >= & iactstart and transaction_date <= &iactend
and customer_id not in (select distinct customer_id from Customers_Active)
order by customer_id;
quit;
/已失效 Table/
请注意,我没有引入 Customers_Active 和 Customers_Inactive table 中不存在的 customer_id。
proc sql;
create table Customers_Lapsed as
select
household_id,
customer_id,
web_order_id,
transaction_date,
sku,
quantity,
original_price
from transaction_vw
where transaction_date >= & lapstart and transaction_date <= & lapend
and customer_id not in (select distinct customer_id from Customers_Active)
and customer_id not in (select distinct customer_id from Customers_Inactive)
order by customer_id;
quit;
回顾一下:最终结果是 3 tables。
- *Customers_Active
- *Customers_InActive
- *Customers_Lapsed
•我正在为所有三个 table 引入相同的变量 •只是日期范围发生了变化 •此外,我不想在 Customers_Inactive table 中包含 customer_id,它已经在 Customers_Active table 中 •和 customer_ids 在失效的 table 中已经在 Customer_Active 和 Customer_inactive tables
再次强调,因为我要提取相同的变量,所以我不想用三个单独的查询来完成这一个。
我会以不同的方式来做这件事。您可以通过几种方式完成,但也许一个 SQL 步骤和一个数据步骤是最简单的。
proc sql;
create table lookup_lastdate as
select customer_id as start, max(transaction_Date) as label,
'LASTDATEF' as fmtname
from transaction_vw
group by customer_id;
quit;
proc format cntlin=lookup_lastdate;
quit;
%let today=11JUN2015;
data customers_active customers_inactive customers_lapsed;
set transaction_vw;
years = intck('YEAR',put(customer_id,LASTDATEF.),"&today."d,'c');
if years < 1 then output customers_active;
else if years < 2 then output customers_inactive;
else if years < 3 then output customers_lapsed;
run;
intck
末尾带有 c
修饰符表示两个日期之间的周期数,因此 1 年表示介于 1 年和 1 年 364 天之间。
这样做的目的是使用更少的数据传递 - 所以,首先计算上次购买的时间,然后输出他们的数据。它在 DoW 循环中甚至可能比这更有效(它执行 1 次真实传递和 2 次虚拟传递,假设数据适合内存)。所以我们使用一种格式来把它拿出来(如果你更喜欢连接,你也可以连接表格,格式更快)。然后我们使用 intck
比较该日期以查看已经过去了多少年,并输出到适当的文件。
附带说明一下,SAS 中有一个偏好,即不放置 3 个这样的文件,而是放置 1 个文件,然后添加一个标志,指示它属于哪个组;然后使用 by
语句分别对每个组进行分析。这进一步简化了代码。为此,只需更改 if
语句以设置标志而不是输出 - 或者跳过 if
并直接分配年份计数。