首单中的即时订单占比
LeetCode 1174 · 分组取首行、占比
面试怎么回答
先圈出首单:WHERE (customer_id, order_date) IN (SELECT customer_id, MIN(order_date) ... GROUP BY customer_id),再对这些首单算 AVG(order_date = customer_pref_delivery_date) * 100。分母是首单数也就是顾客数,这是和上一题的区别。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
同一张配送表,每个顾客最早的订单称为首单(保证唯一)。求所有顾客的首单里,即时订单所占的百分比。
表结构
- Delivery:delivery_id(主键)、customer_id、order_date、customer_pref_delivery_date
思路
先找出每个顾客的首单,再在首单集合上算即时占比。可以用 (customer_id, order_date) IN (每个顾客的最早日期) 圈出首单,也可以用窗口 MIN 给每行挂上首单日期再筛选。
参考解法
写法 1:窗口 MIN 标出首单日期
select round(sum(if(order_date = fo && fo=d,1,0))/count(distinct customer_id)*100,2) immediate_percentage
from
(
select customer_id,order_date,min(order_date)over ( partition by customer_id) fo,
if(order_date=customer_pref_delivery_date,order_date ,null) d
from Delivery
)t1
写法 2:用 (顾客, 最早日期) 圈出首单
select round (
sum(order_date = customer_pref_delivery_date) * 100 /
count(*),
2
) as immediate_percentage
from Delivery
where (customer_id, order_date) in (
select customer_id, min(order_date)
from delivery
group by customer_id
)
易错点
- 分母是顾客数(每人一个首单),不是全部订单数。