题解 | #SQL 16.零食类商品中复购率top3高的商品#

零食类商品中复购率top3高的商品

http://www.nowcoder.com/practice/9c175775e7ad4d9da41602d588c5caf3

零食类商品中复购率top3高的商品

明确题意:

统计零食类商品中复购率top3高的商品。复购率指用户在一段时间内对某商品的重复购买比例,复购率越大,则反映出消费者对品牌的忠诚度就越高,也叫回头率。

此处我们定义:某商品复购率 = 近90天内购买它至少两次的人数 ÷ 购买它的总人数。近90天指包含最大日期(记为当天)在内的近90天。

结果中复购率保留3位小数,并按复购率倒序、商品ID升序排序。


问题分解:

  • 计算每个用户对每个商品是否复购(生成子表t_uid_product_info):
    • 内连接多表:tb_order_detail JOIN tb_order_overall USING(order_id) JOIN tb_product_info USING(product_id)
    • 筛选零食类商品:WHERE tag="零食"
    • 筛选近90天的记录:
      • 计算最小允许日期:DATE_SUB(MAX(event_time), INTERVAL 89 DAY)
      • 筛选:event_time >= (SELECT ... FROM tb_order_overall)
    • 按用户和商品分组:GROUP BY uid, product_id
    • 计算是否复购:IF(COUNT(event_time)>1, 1, 0) as repurchase
  • 按商品分组:GROUP BY product_id
  • 计算复购率:SUM(repurchase) / COUNT(repurchase) as repurchase_rate
  • 保留3位小数:ROUND(x, 3)

细节问题:

  • 表头重命名:as
  • 按复购率倒序、商品ID升序排序:ORDER BY repurchase_rate DESC, product_id
  • 保留top3高的结果:LIMIT 3;

完整代码:

SELECT product_id,
    ROUND(SUM(repurchase) / COUNT(repurchase), 3) as repurchase_rate
FROM (
    SELECT uid, product_id, IF(COUNT(event_time)>1, 1, 0) as repurchase
    FROM tb_order_detail
    JOIN tb_order_overall USING(order_id)
    JOIN tb_product_info USING(product_id)
    WHERE tag="零食" AND event_time >= (
        SELECT DATE_SUB(MAX(event_time), INTERVAL 89 DAY)
        FROM tb_order_overall
    )
    GROUP BY uid, product_id
) as t_uid_product_info
GROUP BY product_id
ORDER BY repurchase_rate DESC, product_id
LIMIT 3;
SQL大厂真题 文章被收录于专栏

大厂真题手把手教你怎么解~

全部评论
我觉得这个题目有问题,应该是用开窗算每个商品的最大时间,而不是一张表的最大时间
4 回复 分享
发布于 2023-08-29 18:52 湖南
datediff是第一个参数的时间减去第二个 你这个用每个event_time减去最大值都是小于等于0的数 都满足小于90这个条件
1 回复 分享
发布于 2023-12-23 18:09 黑龙江
每个商品的最大购买日期好像不太一样吧,需要考虑这个吗?
1 回复 分享
发布于 2022-03-17 22:12
代码其实有点问题,为什么只要90天以内的数据 购买商品的总次数并没有限制90天的
1 回复 分享
发布于 2021-12-22 14:28
这个sum和count真的妙啊,太强了
点赞 回复 分享
发布于 2024-10-12 13:35 上海
where tag='零食' and event_time>= (select max(date(event_time)) from tb_order_overall) -89 我这个时间为啥会出问题呢
点赞 回复 分享
发布于 2024-05-26 11:11 广东
WHERE tag="零食" AND event_time >= ( SELECT DATE_SUB(MAX(event_time), INTERVAL 89 DAY) FROM tb_order_overall ) 把这个地方改成 WHERE tag="零食" AND datediff(event_time, (SELECT MAX(event_time) FROM tb_order_overall) )<90 就不对了,为什么呢,为什么一定要用date_sub写呢?
点赞 回复 分享
发布于 2023-10-06 13:05 北京
秒啊
点赞 回复 分享
发布于 2022-09-08 09:07 广东
event_time >= (SELECT DATE_SUB(MAX(event_time), INTERVAL 89 DAY) 这一步有谁可以帮忙解释下吗?看不明白
点赞 回复 分享
发布于 2022-06-11 20:17
为什么分母是count(repurchase),不理解,有大佬解答一下小萌新的疑惑嘛?
点赞 回复 分享
发布于 2022-04-28 20:10
repurchase已经按uid, product_id分组了,那么 SUM(repurchase) / COUNT(repurchase)为什么会有区别?小白理解不上去了,请教大神
点赞 回复 分享
发布于 2022-04-27 19:03
这里直接count(event_time)好像也没有将status=2的退单情况考虑到
点赞 回复 分享
发布于 2022-01-20 18:12

相关推荐

点赞 评论 收藏
分享
野猪不是猪🐗:现在的环境就是这样,供远大于求。 以前卡学历,现在最高学历不够卡了,还要卡第一学历。 还是不够筛,于是还要求得有实习、不能有gap等等... 可能这个岗位总共就一个hc,筛到最后还是有十几个人满足这些要求。他们都非常优秀,各方面都很棒。 那没办法了,看那个顺眼选哪个呗。 很残酷,也很现实
点赞 评论 收藏
分享
评论
86
3
分享

创作者周榜

更多
牛客网
牛客企业服务