编写SQL查询统计2020年1月连续3天购物的客户数量
嘿,我来帮你搞定这个统计连续3天下单客户的问题!根据你给的数据,我们可以通过几个步骤用SQL实现需求,最终得到预期的结果2。
思路拆解
核心逻辑是:先去掉同一客户单日的重复订单(只保留“某天是否下单”的标记),再通过日期分组找出连续的日期段,最后统计有至少连续3天下单记录的客户数。
完整SQL代码(以MySQL为例)
WITH customer_dates AS ( -- 第一步:过滤2020年1月的订单,同时去重每个客户每天的记录 SELECT DISTINCT Id, order_dt FROM orders WHERE order_dt >= '2020-01-01' AND order_dt < '2020-02-01' ), ranked_dates AS ( -- 第二步:给每个客户的下单日期按时间顺序编号 SELECT Id, order_dt, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY order_dt) AS rn FROM customer_dates ), date_groups AS ( -- 第三步:找出连续日期的分组,统计每组的连续天数 SELECT Id, DATE_SUB(order_dt, INTERVAL rn DAY) AS group_id, COUNT(*) AS consecutive_days FROM ranked_dates GROUP BY Id, group_id -- 筛选出连续天数≥3的分组 HAVING consecutive_days >= 3 ) -- 最后统计符合条件的唯一客户数量 SELECT COUNT(DISTINCT Id) AS customer_count FROM date_groups;
代码解释
customer_datesCTE:因为同一客户单日可能有多笔订单,我们只需要知道某天是否有下单,所以用DISTINCT去重,同时过滤出2020年1月的订单数据。ranked_datesCTE:用窗口函数ROW_NUMBER()给每个客户的下单日期按时间排序编号,连续的日期会对应连续的整数编号。date_groupsCTE:通过DATE_SUB(order_dt, INTERVAL rn DAY)计算分组标识——连续的日期减去对应的编号天数后,会得到同一个group_id。然后分组统计每个客户每个分组的天数,筛选出连续天数≥3的记录。- 最后一步:统计这些符合条件的客户的唯一数量,就是我们要的结果。
不同数据库的适配说明
如果是PostgreSQL环境,date_groups里的分组标识写法需要调整为:
order_dt - (rn || ' days')::interval AS group_id
根据你提供的测试数据,客户A和B都有连续3天(1/1、2/1、3/1)的下单记录,所以最终结果为2,和预期一致。
内容的提问来源于stack exchange,提问作者bzflag
相关产品推荐
相关产品推荐

