订阅更新

市场分析二:卖出的第二件商品是不是最喜欢的品牌

SQL 实战 123 题 · 第 71 题 困难 约 2 分钟读完

LeetCode 1159 · 分组取第 N 行、LEFT JOIN、NULL 处理

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

先用 ROW_NUMBER() OVER (PARTITION BY seller_id ORDER BY order_date) 找到每个卖家的第二笔订单,关联商品表拿品牌;再以用户表为主 LEFT JOIN,用 IF(item_brand = favorite_brand, 'yes', 'no')。没有第二件的用户品牌是 NULL,比较结果不为真,自然输出 no。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

每个用户有一个最喜欢的品牌。按下单日期排序,看每个用户作为卖家卖出的第二件商品的品牌,是否等于他最喜欢的品牌,输出 yes 或 no;卖出不到两件的用户输出 no。

表结构

  • Users:user_id(主键)、join_date、favorite_brand
  • Orders:order_id(主键)、order_date、item_id、buyer_id、seller_id
  • Items:item_id(主键)、item_brand

思路

在订单表里按卖家分区、日期排序编号,取编号为 2 的订单,关联商品表拿到品牌。再用用户表 LEFT JOIN 这个结果:没有第二件的用户品牌为 NULL,item_brand = favorite_brand 结果为 UNKNOWN,IF 会走到 no 分支,正好满足要求。

参考解法

select user_id seller_id, if(item_brand=favorite_brand,'yes','no') 2nd_item_fav_brand 
from Users u
left join 
(
    select i.item_id,seller_id,item_brand
    from Items i
    join 
    (
        select seller_id,item_id,rank() over(partition by seller_id  order by order_date ) rk
        from Orders 
    )t1 
    on i.item_id = t1.item_id 
    where rk  =2
)t2
on u.user_id = t2.seller_id

易错点

  • 以订单为主表会漏掉没卖过东西的用户,必须以用户表为主表。
  • 题目保证同一卖家一天最多卖一件,所以按日期排序编号是确定的;否则要加订单号作为第二排序键。
刷题进度保存在当前浏览器