过滤过去 2 年每年至少有 3 笔交易的客户 Presto/SQL

Posted

技术标签:

【中文标题】过滤过去 2 年每年至少有 3 笔交易的客户 Presto/SQL【英文标题】:Filter customers with atleast 3 transactions a year for the past 2 years Presto/SQL 【发布时间】:2020-08-30 08:25:35 【问题描述】:

我有一个名为 cust_trans 的客户交易表,其中客户进行的每笔交易都存储为一行。我有另一个名为 visit_date 的列,其中包含交易日期。我想过滤过去 2 年每年至少进行 3 次交易的客户。

数据如下所示

Id          visit_date    
----        ------        
1           01/01/2019     
1           01/02/2019     
1           01/01/2019      
1           02/01/2020      
1           02/01/2020      
1           03/01/2020      
1           03/01/2020      
2           01/02/2019 
3           02/04/2019     

我想知道过去两年每年至少光顾 3 次的客户

即。我想要下面的输出。

id    
---       
1       

在客户表中,只有一个人在 2 年内访问了至少 3 次。

我尝试了以下查询,但它只检查总访问量是否大于或等于 3

select id
 from 
  cust_scan
         GROUP  by 
         id
         having count(visit_date) >= 3
         and year(date(max(visit_date)))-year(date(min(visit_date))) >=2

如果有任何帮助、指导或建议,我将不胜感激

【问题讨论】:

过去 2 年是什么意思?日历年? 【参考方案1】:

一种选择是生成一个不同的ids 列表,将其与过去两年交叉连接,然后将原始表与left join 结合起来。然后,您可以汇总计算每个 id 每年的访问次数。最后一步是再次聚合,并使用having 子句进行过滤

select i.id
from (
    select i.id, y.yr, count(c.id) cnt
    from (select distinct id from cust_scan) i
    cross join (values 
        (date_trunc('year', current_date)), 
        (date_trunc('year', current_date) - interval '1' year) 
    ) as y(yr)
    left join cust_scan c 
        on  i.id = c.id
        and c.visit_date >= y.yr
        and c.visit_date <  y.yr + interval '1' year
    group by i.id, y.yr
) t
group by i.id
having min(cnt) >= 3

另一种选择是使用两个相关的子查询:

select distinct id
from cust_scan c
where 
    (
        select count(*) 
        from cust_scan c1 
        where 
            c1.id = c.id
            and c1.visit_date >= date_trunc('year', current_date)
            and c1.visit_date <  date_trunc('year', current_date) + interval '1' year
    ) >= 3
    and (
        select count(*) 
        from cust_scan c1 
        where 
            c1.id = c.id
            and c1.visit_date >= date_trunc('year', current_date) - interval '1' year
            and c1.visit_date <  date_trunc('year', current_date)
    ) >= 3

【讨论】:

但这并不能检查他们是否在一年或两年内每年至少进行 3 次交易。【参考方案2】:

我假设您的意思是日历年。我想我会使用两个级别的聚合:

select ct.id
from (select ct.id, year(visit_date) as yyyy, count(*) as cnt
      from cust_trans ct
      where ct.visit_date >= '2019-01-01'  -- or whatever
      group by ct.id
     ) ct
group by ct.id
having count(*) = 2 and  -- both year
       min(cnt) >= 3;    -- at least three transactions

如果您想要最后两年的完整年份,只需更改子查询中的where 子句即可。

如果您想要相对于当前日期的最近两年,您可以使用类似的想法 - 两个聚合。那将是整整两年,而不是 1 年和当年的一小部分。

【讨论】:

以上是关于过滤过去 2 年每年至少有 3 笔交易的客户 Presto/SQL的主要内容,如果未能解决你的问题,请参考以下文章

在 Bigquery 中计算过去 3 个月内活跃的供应商数量

标记活跃客户 - 每月至少一笔交易

客户每笔交易之间的平均时间

为啥每笔交易都算作一个客户?

JavaScript 最佳实践通过三个因素过滤数组

Facebook币Libra学习-3.小试牛刀第一笔交易