【京东】按首单香水家族统计四步有序漏斗
JOIN 连接聚合函数窗口函数CASE WHEN日期函数用户行为分析漏斗分析面试真题
题目描述
来源:京东 SQL 面试真题
某调香工作室想了解客户的“嗅觉旅程”:客户从第一瓶香水开始,是会深耕同一家族,还是会主动探索新家族?
请按“客户首单香水家族”分组,统计一个严格保序的四步漏斗。后一步客户必须是前一步客户的子集。
数据表
t_perfume 香水产品档案表
| 字段 | 类型 | 说明 |
|---|---|---|
| perfume_id | BIGINT | 香水编号 |
| perfume_name | VARCHAR(64) | 香水名称 |
| family | VARCHAR(16) | 香水家族:floral / woody / citrus / oriental / fresh / gourmand |
| price | DECIMAL(7,2) | 标价(元) |
t_purchase 购买流水表
| 字段 | 类型 | 说明 |
|---|---|---|
| purchase_id | BIGINT | 购买编号 |
| customer_id | BIGINT | 客户编号 |
| perfume_id | BIGINT | 香水编号,关联 t_perfume.perfume_id |
| purchase_date | DATE | 购买日期 |
| qty | TINYINT | 购买数量 |
| pay_amount | DECIMAL(8,2) | 实付金额 |
漏斗定义
只考虑 purchase_date 在 2025-01-01 至 2025-12-31 之间的购买。对每位客户单独判定:
- D0 首单:取客户 2025 年内最早的一笔购买;若同一天有多单,取
purchase_id最小的一笔。该笔香水的family为first_family。 - Step 2 同家族复购:在 D0 后第 1~30 天(含边界)存在至少一笔购买,且
family = first_family。 - Step 3 异家族扩展:已满足 Step 2,并在 D0 后第 31~60 天存在至少一笔
family <> first_family的购买。 - Step 4 三家族覆盖:已满足 Step 3,且在 D0 至 D0 后第 90 天(含边界)内累计接触的不同
family数量不少于 3。
输出字段
| 字段 | 说明 |
|---|---|
| first_family | 首单香水家族 |
| step1_first_buyer_cnt | 该家族作为首单家族的客户人数 |
| step2_same_family_repeat_cnt | 满足 Step 2 的客户人数 |
| step3_cross_family_cnt | 同时满足 Step 2 和 Step 3 的客户人数 |
| step4_three_family_cnt | 同时满足 Step 2、Step 3 和 Step 4 的客户人数 |
| step2_rate | Step 2 / Step 1 × 100,四舍五入保留 2 位;分母为 0 时输出 0.00 |
| step3_rate | Step 3 / Step 2 × 100,口径同上 |
| step4_rate | Step 4 / Step 3 × 100,口径同上 |
只输出 step1_first_buyer_cnt > 0 的家族。结果先按 step1_first_buyer_cnt 降序,再按 first_family 升序。
数据样例
| perfume_idPKBIGINT | perfume_nameVARCHAR(64) | familyVARCHAR(16) | priceDECIMAL(7, 2) |
|---|---|---|---|
| 1 | Rose Dawn | floral | 399 |
| 2 | Peony Mist | floral | 459 |
| 3 | Cedar Path | woody | 529 |
| 4 | Sandal Night | woody | 599 |
| 5 | Bergamot Sun | citrus | 369 |
| 6 | Orange Grove | citrus | 329 |
| 7 | Amber Veil | oriental | 629 |
| 8 | Mint Air | fresh | 299 |
输入数据显示 8 / 9 行
SQL 编辑器正在保存草稿...
Ctrl + Enter 运行
正在加载 SQL 编辑器...
运行你的 SQL 查询后,结果将显示在这里