我有一个评估日期列表,存储在表格日期列表中。从技术上讲,每个评估期都有两列, start_date 和 end_date 。肯定需要使用end_date,但start_date可能不需要。我只关心已完成的期间,因此,例如,2016-01-01至2016-07-01期间正在进行但尚未完成。所以,它不在表格中。
start_date end_date
2012-01-01 2012-07-01
2012-07-01 2013-01-01
2013-01-01 2013-07-01
2013-07-01 2014-01-01
2014-01-01 2014-07-01
2014-07-01 2015-01-01
2015-01-01 2015-07-01
2015-07-01 2016-01-01
我有一个单独的表格,列出了客户的累计销售额, sales_table ,其中有三列, customer_ID , cumul_sales , transaction_date < / strong>即可。例如,假设客户4793在2014年2月14日购买了价值100美元的东西,在2014年3月30日购买了价值200美元的东西,在7/27/2014购买了75美元,该表格将包含以下行:
customer_ID cumul_sales transaction_date
4793 100 2014-02-14
4793 300 2014-03-30
4793 375 2014-07-27
现在,对于每个评估日期和每个客户,我想知道该客户评估日期的累计销售额是多少?如果客户在评估日期之前没有购买任何东西,那么我根本不希望该客户对应于所述评估日期。这将存储在名为 sales_by_eval 的新表格中,其中列 customer_ID , cumul_sales , eval_date 。对于上面的示例客户,我将拥有以下行:
customer_ID cumul_sales eval_date
4793 300 2014-07-01
4793 375 2015-01-01
4793 375 2015-07-01
4793 375 2016-01-01
我可以做到这一点,但我希望以有效的方式做到这一点,所以我不需要为每个评估日期读取一次数据。如果sales_table和40个评估日期中有很多行,那么读取数据40次将是一个很大的浪费,每个评估日期一次。只有一次读取数据是否可能,例如?
当前流程的基本思想是每个评估期循环一次的宏循环。每个循环都有一个数据步骤,用于创建一个新表(每个循环一个表),以检查每个事务,以查看它是否在相应评估期的end_date之前或之后发生。也就是说,每个表都包含在该评估日期之前或之后发生的所有事务,但不包括之后发生的所有事务。然后,后面的数据步骤使用“最后”。在评估日期之前仅获得每个客户的最后一笔交易。最后,创建的所有各种表在另一个数据步骤中重新组合在一起,它们都在SET语句中列出。
这是在SAS中,所以SAS可以做的任何事情,包括SQL和宏,对我都没问题。
答案 0 :(得分:1)
在SAS中,当您使用group by语句时,您仍然可以不在select语句中使用分组变量,如下所示:
proc sql;
create table sales_by_eval as
select s.customer_ID, s.cumul_sales, d.end_date as eval_date
from datelist d
join sales_table s
on d.end_date > s.transaction_date
group by s.customer_ID, d.end_date
having max(s.transaction_date) = s.transaction_date
;
quit;
这意味着对于所选变量的每个组合,SAS将使用在定义的组内汇总的度量返回rekord。要将结果限制为事务值的最后一个状态,请使用having condition,其中只选择在s.customer_ID,d.end_date组中具有transaction_date等于max(transaction_date)的记录。