市场分析二:卖出的第二件商品是不是最喜欢的品牌
LeetCode 1159 · 分组取第 N 行、LEFT JOIN、NULL 处理
面试怎么回答
先用 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
易错点
- 以订单为主表会漏掉没卖过东西的用户,必须以用户表为主表。
- 题目保证同一卖家一天最多卖一件,所以按日期排序编号是确定的;否则要加订单号作为第二排序键。