基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

统计用户在搜索某个关键词且“无搜索结果”后,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 代码,计算:

  1. 分母:经历过“无搜索结果”(result_count = 0)的去重用户总数。
  2. 分子:在发生“无搜索结果”后 10分钟内,通过 “为您推荐” 渠道成功下单的去重用户总数。
  3. 比例:分子 / 分母,结果保留两位小数(以百分比形式展示,例如: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'
  • 避坑指南:面试时一定要主动向面试官确认使用的是哪种 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 分钟内通过推荐位下单,完美符合,计入分子与分母
00:00
00:00