题解 | #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大厂真题 文章被收录于专栏

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

全部评论
我觉得这个题目有问题,应该是用开窗算每个商品的最大时间,而不是一张表的最大时间
7 回复 分享
发布于 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

相关推荐

评论
97
3
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
8136次浏览 75人参与
# 你的实习产出是真实的还是包装的? #
1493次浏览 37人参与
# 巨人网络春招 #
11265次浏览 223人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7266次浏览 40人参与
# 简历第一个项目做什么 #
31433次浏览 319人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
186697次浏览 1118人参与
# MiniMax求职进展汇总 #
23529次浏览 305人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152171次浏览 887人参与
# 研究所笔面经互助 #
118827次浏览 577人参与
# 重来一次,我还会选择这个专业吗 #
433206次浏览 3924人参与
# 简历中的项目经历要怎么写? #
309816次浏览 4176人参与
# 面试紧张时你会有什么表现? #
30452次浏览 188人参与
# 你今年的平均薪资是多少? #
212883次浏览 1039人参与
# AI时代,哪些岗位最容易被淘汰 #
63109次浏览 773人参与
# 我的求职精神状态 #
447904次浏览 3128人参与
# 你最满意的offer薪资是哪家公司? #
76323次浏览 374人参与
# 正在春招的你,也参与了去年秋招吗? #
362991次浏览 2635人参与
# 你怎么看待AI面试 #
179654次浏览 1206人参与
# 牛客AI文生图 #
21374次浏览 237人参与
# 职能管理面试记录 #
10766次浏览 59人参与
# 网易游戏笔试 #
6420次浏览 83人参与
# 腾讯音乐求职进展汇总 #
160518次浏览 1108人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务