Proc SQL:基于回溯期的新客户和继续客户

时间:2019-03-04 04:43:23

标签: sas

我有以下数据:

wei 01feb2018    car
wei 02feb2018    car
wei 02mar2019    bike
carlin 01feb2018 car
carlin 05feb2018 bike
carlin 07mar2018 bike
carlin 01mar2019 car

我想确定新的和继续的客户,如果一个客户在最近12个月内没有购买任何商品,那么它将成为一个新客户。要求的输出就像

wei 01feb2018    car     new
wei 02feb2018    car     cont.
wei 02mar2019    bike    new
carlin 01feb2018 car     new
carlin 05feb2018 bike    cont.
carlin 07mar2018 bike    cont.
carlin 01mar2019 car     new

现在,如果客户在同一个月内为前客户购买了任何商品,则在01jan上购买了一辆汽车,在15jan上购买了自行车,那么我希望两个客户将a归类为1月份的新客户,而在另一个报告中我希望客户a作为新内容并继续。

我正在尝试但没有弄清楚逻辑-

proc sql;
select a.*,(select count(name) from t where intnx("month",-12,a.date) >= 356) 
as tot
from t a;
Quit;

2 个答案:

答案 0 :(得分:0)

您可以使用retain

proc sort data=test out=test2;
  by name  type date;
run;

data test2 ;
set test2;
 retain retain 'new';
 by name  type date;
   if first.type then retain='new';
   else retain='con';
run;

proc sort data=test2 out=test2;
  by name  date; 
run;

输出:

+--------+-----------+------+--------+
|  name  |   date    | type | retain |
+--------+-----------+------+--------+
| carlin | 01FEB2018 | car  | new    |
| carlin | 05FEB2018 | bike | new    |
| carlin | 01MAR2019 | car  | con    |
| wei    | 01FEB2018 | car  | new    |
| wei    | 02FEB2018 | car  | con    |
| wei    | 02MAR2019 | bike | new    |
+--------+-----------+------+--------+

答案 1 :(得分:0)

您似乎想要两个不同的“状态”变量,一个用于上一年的连续性,另一个用于在月份中的连续性

在SQL中,存在性自反相关子查询结果可以作为满足 over in 条件的行的案例测试。日期算术用于计算相隔的天数,而INTCK用于计算相隔的月数:

data have; input
customer $ date& date9. item& $; format date date9.; datalines;
wei     01feb2018  car
wei     02feb2018  car
wei     02mar2019  bike
carlin  01feb2018  car
carlin  05feb2018  bike
carlin  07mar2018  bike
carlin  01mar2019  car
run;

proc sql;
  create table want as
  select *,
    case
      when exists 
      (
        select * from have as inner 
        where inner.customer=outer.customer
          and (outer.date - inner.date) between 1 and 365
      ) 
      then 'cont.'
      else 'new'
    end as status_year,
    case
      when exists 
      (
        select * from have as inner 
        where inner.customer=outer.customer
          and outer.date > inner.date
          and intck ('month', outer.date, inner.date) = 0
      ) 
      then 'cont.'
      else 'new'
    end as status_month
  from have as outer
  ;
quit;