每个产品最近一次的订单(含同一天多笔)
LeetCode 1549 · 分组取最新、RANK 保留并列、多字段排序
面试怎么回答
RANK() OVER (PARTITION BY product_id ORDER BY order_date DESC) 取 rk = 1,同一天的多笔订单都会保留;关联产品名后按 product_name、product_id、order_id 排序。「最新一条」要不要包含并列,决定了用 RANK 还是 ROW_NUMBER。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
顾客表、订单表、产品表。找出每个产品最近一个下单日期的所有订单(同一天可能有多笔),按产品名、产品 ID、订单 ID 升序排列。从没被下单的产品不输出。
表结构
- Customers:customer_id(主键)、name
- Orders:order_id(主键)、order_date、customer_id、product_id
- Products:product_id(主键)、product_name、price
思路
按产品分区、订单日期降序排名,取排名第一的订单。同一天可能有多笔,都要保留,所以用 RANK 而不是 ROW_NUMBER。从订单表出发,没被下单的产品自然不会出现。
参考解法
select product_name,product_id,order_id,order_date
from
(
select product_name ,o.product_id ,order_id,order_date ,
rank() over(partition by o.product_id order by order_date desc) rk
from Orders o left join Products p
on o.product_id =p.product_id
)t1
where rk =1
order by product_name,product_id,order_id
易错点
- ROW_NUMBER 会只留下最近一天的其中一笔订单。