计算每个客户在6个月内发生的特定代码

时间:2016-01-12 13:39:45

标签: sql tsql sql-server-2012

我有一张包含以下内容的表格:

customerid | date (dmy) | productid

   John    |    1-3-14    |     A
   John    |    7-5-14    |     Y
   John    |    8-5-14    |     Y
   John    |    1-10-15   |     B
   John    |    1-11-15   |     Y
   Pete    |    1-7-15    |     Y

我需要了解客户X在六个月内购买产品Y的频率。

一段时间的开始被定义为客户第一次购买A,B,C或Y中的一种产品。一段时间的结束时间恰好是六个月之后。

当客户再次购买产品A,B,C或Y中的一个时,下一个时段开始。

所以输出应该是

customerid | period-start | period-end | countofY
   John    |    1-3-14    |   8-5-14   |    2
   John    |    1-10-15   |   1-11-15  |    1
   Pete    |    1-7-15    |   1-7-15   |    1

2 个答案:

答案 0 :(得分:0)

;WITH CTE_DateRanges AS (
    SELECT
        customerid,
        productid,
        MIN(purchase_date) AS period_start,
        DATEADD(MM, 6, MIN(purchase_date)) AS period_end
    FROM
        My_Table
    GROUP BY
        customerid,
        productid
)
SELECT
    DR.customerid,
    DR.productid,
    DR.period_start,
    DR.period_end,
    COUNT(*)
FROM
    CTE_DateRanges DR
INNER JOIN My_Table MT ON
    MT.customerid = DR.customerid AND
    MT.productid = DR.productid AND
    MT.purchase_date BETWEEN DR.period_start AND DR.period_end
GROUP BY
    DR.customerid,
    DR.productid,
    DR.period_start,
    DR.period_end,

答案 1 :(得分:0)

SELECT c.Customerid, MIN(c.pdate) AS startperiod, c1.endperiod, 
(
    SELECT COUNT(temp.productid) FROM Customer temp 
    WHERE temp.Customerid = c.Customerid
    AND temp.pdate >= MIN(c.pdate)
    AND temp.pdate <= c1.endperiod 
    GROUP BY temp.productid HAVING temp.productid ='Y'
)AS countOfY 
FROM Customer c 
CROSS APPLY
(
    SELECT TOP 1 c1.pdate AS endperiod  
    FROM Customer c1 
    WHERE c1.Customerid = c.Customerid
    AND c1.pdate >= c.pdate
    AND 
    (
        DATEDIFF(MONTH, c.pdate, c1.pdate) < 6  
        OR 
        (
            SELECT TOP 1 t.pdate FROM Customer t
            WHERE t.Customerid = c.Customerid
            AND t.pdate < c1.pdate
        ) IS NULL       
    )   
    ORDER BY c1.pdate DESC
)AS c1 GROUP BY c1.endperiod, c.Customerid