通过购买之间的差异,缩短客户购买时间

时间:2018-01-23 19:58:37

标签: sql sql-server

我正在使用SQL Server 2012,我需要弄清楚如何为已购买产品的客户提取跟踪期,其中:

默认跟踪期为购买日期后12个月(见Smith,Jones,Thomas)。

如果客户在12个月内购买了其他产品,则会延长跟踪期。因此,如果客户在2106年6月购买物品,我们将追踪到2017年5月。如果该客户在2016年8月购买了其他物品,我希望该记录显示追踪期是从2016年6月开始(首次购买)日期)到2017年8月(见Carpenter)。只要客户在跟踪期结束前继续购买产品,就应该继续这个过程(见戴维斯)。

如果客户在没有购买其他产品的情况下运行12个月,然后再购买产品,我需要两条记录,每个跟踪期一个(参见Henderson)。

使用LEAD,我能够确定客户是单次购买还是多次购买,以及购买之间的时间。这是我的代码:

SELECT DISTINCT 
    CustomerID,
    PurchaseDate,
    ISNULL(LEAD(PurchaseDate) OVER (PARTITION BY CustomerID ORDER BY CustomerID, PurchaseDate), DATEADD(MONTH, 12, PurchaseDate)) TrackThroughDate,
    DATEDIFF(MONTH, PurchaseDate, ISNULL(LEAD(PurchaseDate) OVER (PARTITION BY CustomerID ORDER BY CustomerID, PurchaseDate), DATEADD(MONTH, 12, PurchaseDate))) AS NumberOfMonths
FROM 
    PurchaseDetail
WHERE 
    PurchaseDate > '2014/06/30'
ORDER BY 
    CustomerID, PurchaseDate

这样的一些样本数据是(月份的数量没有必要,我只包括它以使结果中的条件更容易识别):

enter image description here

所以我需要的是:

enter image description here

有关良好方法的任何建议吗?

1 个答案:

答案 0 :(得分:1)

您可以使用lag(),运行总和以及某些锁定来指定跟踪期:

select pd.customerid,
       sum(case when prev_purchasedate > dateadd(year, -1, purchasedate)
                then 0 else 1
           end) over (partition by customerid order by purchasedate) as trackingperiod
from (select pd.*,
             lag(purchasedate) over (partition by customerid order by purchasedate) as prev_purchasedate
      from purchasedetail pd
     ) pd;

这根据购买日期定义跟踪期的开始。然后,开头的累积总和定义跟踪周期本身。

如果您想总结一下这些,那么逻辑只会在该期间的最大日期增加一年:

select customerid, min(purchasedate) as purchasedate,
       dateadd(year, 1, max(purchasedate)) as trackthroughdate
from (select pd.*,
             sum(case when prev_purchasedate > dateadd(year, -1, purchasedate)
                      then 0 else 1
                 end) over (partition by customerid order by purchasedate) as trackingperiod
      from (select pd.*,
                   lag(purchasedate) over (partition by customerid order by purchasedate) as prev_purchasedate
            from purchasedetail pd
           ) pd
     ) pd
group by customerid, trackingperiod;