市场分析一:每个用户 2019 年的买家订单数
LeetCode 1158 · 先聚合再左关联、零值补齐
面试怎么回答
在订单表里先按 2019 年过滤、按 buyer_id 计数,再用用户表 LEFT JOIN 这个结果,IFNULL 补 0。如果直接左关联订单表,年份条件要放在 ON 里,否则零订单用户会丢;另外日期条件我会写成区间而不是 YEAR() 函数,方便走索引。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
用户表有注册日期,订单表记录买家、卖家和下单日期。输出每个用户的注册日期,以及他在 2019 年作为买家下的订单数;没下过单的显示 0。
表结构
- Users:user_id(主键)、join_date、favorite_brand
- Orders:order_id(主键)、order_date、item_id、buyer_id、seller_id
- Items:item_id(主键)、item_brand
思路
先在订单表里过滤 2019 年、按买家计数,再用用户表 LEFT JOIN 这个结果,没有订单的用户计数为空,用 IFNULL 变成 0。先聚合再关联,比关联后再分组更省。
参考解法
select user_id buyer_id,join_date, ifnull(cnt,0)orders_in_2019
from Users u left join
(select buyer_id,count(*) cnt
from Orders
where year(order_date) = 2019
group by buyer_id
)t1
on u.user_id =t1.buyer_id
易错点
- 用户表直接 LEFT JOIN 订单表,然后把年份条件写在 WHERE 里,没有 2019 年订单的用户会被过滤掉。
YEAR(order_date) = 2019对列套函数会让索引失效,大表上用order_date >= '2019-01-01' AND order_date < '2020-01-01'。