递归跟踪购买月份的 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 查询的主要内容,如果未能解决你的问题,请参考以下文章