递归跟踪购买月份的 SQL 查询

Posted

技术标签:

【中文标题】递归跟踪购买月份的 SQL 查询【英文标题】:SQL Query to recursively track month of purchase 【发布时间】:2019-03-10 05:14:33 【问题描述】:

我有一张带有客户 ID 和购买月份的表格。对于每个客户,我首先需要在他们购买的第一个月对他们进行细分,即,如果客户在 2017 年 6 月 10 日进行了首次购买,那么他们属于 2017 年 6 月的存储桶。请参见下面的示例数据表。

然后,对于该客户的每次后续购买(例如从 2017 年 6 月开始),我们需要跟踪该月。例如,如果 2017 年 6 月的客户在 2017 年 6 月 25 日进行了第二次购买,并在 2017 年 8 月 11 日进行了第三次购买。那么第二次购买将计入第一个月(第一次交易后 30 天内),第三次购买将计入第三个月,因为 2017 年 8 月 11 日和 2017 年 6 月 10 日之间的差异是 62 天,介于 61 和 90 天之间,因此在第 3 个月。

请参阅下面的示例输出表,尽管我需要百分比形式(第一个月、第二个月等的客户百分比)。在表格中,我们显示了 2017 年 1 月进行首次交易的所有客户,以及随后几个月进行交易的客户数量。

需要为每个客户进行此跟踪。虽然我相信我对第一部分感到满意​​,其中我需要对每个客户进行细分,但我可以根据第一个或分区来做到这一点。

我不确定如何为后续事务递归执行此操作。

提前感谢您的帮助!

【问题讨论】:

请用您正在使用的数据库标记您的问题。 我正在使用上面提到的 SQL。虽然我可以使用不同类型的 SQL(Hive 或 Teradata),但我并不担心。这有帮助吗?谢谢! 【参考方案1】:

您只需使用窗口函数定义原始月份,然后进行条件聚合。

你没有提到数据库,但这是一个想法:

select to_char(first_purchase_date, 'YYYY-MM') as yyyymm,
       sum(case when months_between(first_purchase_date, purchase_date) = 1 then 1 else 0 end) as purchases_1,
       sum(case when months_between(first_purchase_date, purchase_date) = 1 then 1 else 0 end) as purchases_2,
       . . .
from (select t.*,
             min(purchase_date) over (partition by customer_id) as first_purchase_date
      from t
     ) t
group by first_purchase_date;

我发明了months_between()to_char() 函数,但你应该明白了。

上述跟踪购买。要获得客户,您可以使用:

       (count(distinct case when months_between(first_purchase_date, purchase_date) = 1 then customer_id) /
        count(distinct customer_id)
       ) as month_1_ratio

【讨论】:

【参考方案2】:

您可以使用滞后功能创建一个“以前的购买”列。

Lag(purchasemonth,1) over(partition. by customerid order by purchasemonth) as [PreviousPurchaseDate]

然后简单地做一个你想要的日期差异和存储桶。

【讨论】:

我不确定这是否有效,因为只有在我为客户进行 2 笔交易时才会小心。但是一位客户可能有 5 笔交易,而另一位客户可能只有 2 笔。我需要根据第一个交易日期存储所有交易。

以上是关于递归跟踪购买月份的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

sql server 递归查询

sql 递归查询

sql 怎么递归查询的方法:

SQL递归查询知多少

关于SQL递归查询问题

ms sql 2005 递归查询如何实现