统计用户在搜索某个关键词且“无搜索结果”后,10 分钟内通过底部“为您推荐”位成功下单的用户比例
面试题:无搜索结果后的推荐位转化率分析
1. 题目背景
在电商、内容或搜索类产品中,“无搜索结果(Zero Results)”是极易造成用户流失的痛点。为了挽留用户,通常会在页面底部展示“为您推荐”模块。本题要求评估这一挽留策略的效果,统计在经历“无搜索结果”后,10分钟内通过底部“为您推荐”位成功下单的用户比例(占所有经历过无搜索结果的去重用户比例)。
2. 示例数据
表 1:用户搜索日志表 user_search_log
记录用户的搜索行为及结果数量。
| user_id | search_time | keyword | result_count |
|---|---|---|---|
| 101 | 2023-10-24 10:00:00 | 苹果18代 | 0 |
| 102 | 2023-10-24 10:10:00 | 华为Mate100 | 0 |
| 103 | 2023-10-24 10:15:00 | 小米汽车 | 0 |
| 104 | 2023-10-24 10:20:00 | 运动跑步鞋 | 15 |
| 105 | 2023-10-24 10:30:00 | 概念飞行包 | 0 |
| 106 | 2023-10-24 10:40:00 | 智能意念控制仪 | 0 |
表 2:订单日志表 order_log
记录用户下单成功的详细信息。
| order_id | user_id | order_time | order_source |
|---|---|---|---|
| ord_001 | 101 | 2023-10-24 10:05:00 | 为您推荐 |
| ord_002 | 102 | 2023-10-24 10:25:00 | 为您推荐 |
| ord_003 | 103 | 2023-10-24 10:18:00 | 首页大促 |
| ord_004 | 104 | 2023-10-24 10:22:00 | 为您推荐 |
| ord_005 | 106 | 2023-10-24 10:41:00 | 为您推荐 |
3. 面试要求
请编写 SQL 代码,计算:
- 分母:经历过“无搜索结果”(
result_count = 0)的去重用户总数。 - 分子:在发生“无搜索结果”后 10分钟内,通过 “为您推荐” 渠道成功下单的去重用户总数。
- 比例:分子 / 分母,结果保留两位小数(以百分比形式展示,例如:
40.00%)。
4. SQL 解答(MySQL 8.0 标准)
sql
SELECT
CONCAT(
ROUND(
COUNT(DISTINCT CASE WHEN o.order_id IS NOT NULL THEN s.user_id END)
/ COUNT(DISTINCT s.user_id) * 100,
2
),
'%'
) AS success_order_user_ratio
FROM (
-- 步骤 1:筛选出所有搜索无结果的用户及其搜索时间
SELECT DISTINCT user_id, search_time
FROM user_search_log
WHERE result_count = 0
) s
LEFT JOIN order_log o
ON s.user_id = o.user_id
AND o.order_source = '为您推荐'
AND o.order_time >= s.search_time
AND o.order_time <= TIMESTAMPADD(MINUTE, 10, s.search_time);
预期输出结果:
| success_order_user_ratio |
|---|
| 40.00% |
5. SQL 深度剖析与面试考点
考点 1:漏斗分析与 LEFT JOIN 的巧妙应用
在计算转化率时,必须保证“先搜索、后下单”的时序性。
- 通过将搜索表作为主表,左关联(
LEFT JOIN)订单表,可以保留所有“无搜索结果”的用户(保证分母完整)。 - 关联条件中直接限制
o.order_time >= s.search_time确保了事件发生的先后顺序。
考点 2:时间窗口限制(Time Window)
题目要求“10分钟内”,SQL 中有多种处理方式:
- 标准写法:使用
TIMESTAMPADD(MINUTE, 10, s.search_time)。 - 其他数据库实现:
- Hive/Spark SQL:
unix_timestamp(o.order_time) - unix_timestamp(s.search_time) <= 600 - PostgreSQL:
o.order_time <= s.search_time + INTERVAL '10 minutes'
- Hive/Spark SQL:
- 避坑指南:面试时一定要主动向面试官确认使用的是哪种 SQL 方言,展示你对不同引擎(Hive/MySQL)时间函数差异的了解。
考点 3:去重统计(Distinct Count)
- 为什么要用
COUNT(DISTINCT)?- 一个用户在一天内可能多次搜索无结果,也可能多次下单。
- 题目要求的是“用户比例”(User Ratio),而不是“行为次数比例”(Event Ratio),因此必须对
user_id进行去重。
CASE WHEN o.order_id IS NOT NULL THEN s.user_id END确保只有满足关联条件(即10分钟内通过推荐位下单)的用户才会被纳入分子的去重计数中。
考点 4:数据边界测试(Edge Cases)
面试官会通过数据设计来测试你的 SQL 鲁棒性:
- User 102:虽然通过“为您推荐”下单,但下单时间(10:25)距离搜索时间(10:10)相差15分钟,不应计入分子。
- User 103:虽然在10分钟内下单(10:18),但订单来源是“首页大促”,不应计入分子。
- User 104:虽然在10分钟内通过“为您推荐”下单,但其搜索结果数为 15(非无搜索结果),不应计入分母与分子。
- User 106:在 1 分钟内通过推荐位下单,完美符合,计入分子与分母。