基于BigQuery实现时间戳月度分桶及用户首单周期累计留存分析
如何在BigQuery中基于首次下单日期计算多周期累计订单金额与数量?
当然可以实现!针对你提出的需求,我们可以通过窗口函数获取用户首次下单日期,再结合条件聚合函数来按30天周期统计累计数据,完全适配BigQuery的SQL语法。
实现思路拆解
- 标记用户首次下单日期:先为每个用户确定首次下单的基准日期,这是后续周期计算的核心参考点。
- 计算订单与首次下单的天数差:关联原订单数据,算出每笔订单距离用户首次下单的天数间隔,用来判断订单属于哪个统计周期。
- 按周期聚合统计:用条件筛选+聚合函数,分别统计30/60/90/120天内的累计订单金额和数量。
完整BigQuery SQL代码
WITH user_first_order AS ( -- 第一步:获取每个用户的首次下单日期 SELECT user_id, MIN(date) AS first_order_date FROM `your-project.your-dataset.your-table` -- 替换为你的实际表路径 GROUP BY user_id ), order_with_days_since_first AS ( -- 第二步:关联原订单表,计算每笔订单距首次下单的天数差 SELECT o.*, u.first_order_date, DATE_DIFF(o.date, u.first_order_date, DAY) AS days_since_first FROM `your-project.your-dataset.your-table` o JOIN user_first_order u ON o.user_id = u.user_id ) -- 第三步:按用户和首次下单日期聚合,统计各周期累计数据 SELECT first_order_date, user_id, -- 30天内累计金额&订单数 SUM(CASE WHEN days_since_first <= 30 THEN price ELSE 0 END) AS 30d_p, COUNT(CASE WHEN days_since_first <= 30 THEN order_id ELSE NULL END) AS 30d_c, -- 60天内累计金额&订单数(包含前30天数据) SUM(CASE WHEN days_since_first <= 60 THEN price ELSE 0 END) AS 60d_p, COUNT(CASE WHEN days_since_first <= 60 THEN order_id ELSE NULL END) AS 60d_c, -- 90天内累计金额&订单数 SUM(CASE WHEN days_since_first <= 90 THEN price ELSE 0 END) AS 90d_p, COUNT(CASE WHEN days_since_first <= 90 THEN order_id ELSE NULL END) AS 90d_c, -- 120天内累计金额&订单数 SUM(CASE WHEN days_since_first <= 120 THEN price ELSE 0 END) AS 120d_p, COUNT(CASE WHEN days_since_first <= 120 THEN order_id ELSE NULL END) AS 120d_c FROM order_with_days_since_first GROUP BY first_order_date, user_id ORDER BY first_order_date, user_id;
关键逻辑说明
user_first_orderCTE:用MIN(date)聚合得到每个用户的首次下单日期,确保每个用户只有一条基准记录。order_with_days_since_firstCTE:通过JOIN把原订单数据和用户首次下单日期关联,用DATE_DIFF函数计算天数差——这里要注意如果你的date字段是TIMESTAMP类型,需要先转成DATE类型(比如DATE(o.date))再计算。- 条件聚合:用
CASE WHEN筛选出对应周期内的订单,SUM统计累计金额(非周期内金额设为0),COUNT统计订单数量(非周期内订单ID设为NULL,因为COUNT只会统计非NULL值)。
示例数据验证
针对你提供的订单数据,运行上述SQL后会得到和你期望完全一致的结果:
| first_order_date | user_id | 30d_p | 30d_c | 60d_p | 60d_c | 90d_p | 90d_c | 120d_p | 120d_c |
|---|---|---|---|---|---|---|---|---|---|
| 2020-06-02 | abc | 240 | 2 | 340 | 3 | 340 | 3 | 440 | 4 |
额外注意事项
- 记得替换代码中的
your-project.your-dataset.your-table为你实际的BigQuery表路径。 - 如果需要扩展更多统计周期(比如150天、180天),只需要复制对应的
SUM和COUNT语句,修改天数阈值即可。 - 如果存在用户同一天多次下单的情况,该逻辑也能正确统计,不会遗漏任何订单。
内容的提问来源于stack exchange,提问作者Alex Fox




