SQL - 在两个日期之间分组和过滤

问题描述

我有一个这样的消费表:

Account_ID | Product_ID | Date_Purchased | Amount_Purchased
         1 |         57 |       05/26/20 |               14
         7 |         14 |       09/18/19 |               12
        45 |         104 |      08/27/20 |                3

我想要做的是对每个 Product_ID 查看产品可用的前 30 天(假设开始日期是给定产品消费表中 Date_Purchased 的最小值) 并计算购买了 >= 10 个单位 (Account_ID) 的唯一 Amount_Purchased 数量,以及在该 30 天窗口内活动的唯一帐户总数(其中“活跃”意味着他们在这 30 天内购买了任何东西),这样我就可以获得在 30 天内购买了至少 10 件产品的活跃帐户的百分比。

我可以做这样的事情来获得每个独特的 Product_ID 的 30 天窗口:

SELECT 
    Product_ID,MIN(Date_Purchased) as Start_Date,TO_CHAR(DATEADD(day,30,Start_Date),'YYYY-MM-DD') as End_Date
FROM consumption_table
GROUP BY Product_ID

但我正在苦苦思索如何在每个 30 天的窗口内过滤 Date_Purchased,然后计算活跃的不同帐户,以及购买 >= 10 件的帐户数。如果我只有一个 30 天的窗口/产品要查看,我显然可以把它放在 WHERE 中,但我有数百个 Product_ID。这可以使用 GROUP BYHAVING 来完成吗?可能与 CASE WHEN 一起使用吗?对不起,如果这是一个非常基本的问题。我想要的输出看起来像这样:

Product_ID | Start_Date | End_Date | Active_During_30_Days | Purchased_10_Units | Pct
         1 |   06/18/20 | 07/18/20 |                356891 |               5467 | 0.01532

非常感谢您的帮助。

解决方法

使用窗口函数:

SELECT Product_ID,COUNT(DISTINCT CASE WHEN amount_purchased > 10 THEN Account_Id END) as num_big_accounts,COUNT(DISTINCT Account_ID) as num_accounts,( COUNT(DISTINCT CASE WHEN amount_purchased > 10 THEN Account_Id END) /
         COUNT(DISTINCT Account_ID)
       ) as ratio
FROM (SELECT c.*,MIN(Start_Date) OVER (PARTITION BY Product_ID) as min_Start_date
      FROM consumption_table c
     ) c
WHERE Start_Date < min_Start_Date + INTERVAL '30 day'
GROUP BY Product_ID;

注意:这使用标准日期函数。您可能需要针对您的数据库进行调整。