LeetCode--1174. 即时食物配送 II

48 阅读3分钟

1 题目描述

配送表: Delivery

+-----------------------------+---------+
| Column Name                 | Type    |
+-----------------------------+---------+
| delivery_id                 | int     |
| customer_id                 | int     |
| order_date                  | date    |
| customer_pref_delivery_date | date    |
+-----------------------------+---------+

delivery_id 是该表中具有唯一值的列。 该表保存着顾客的食物配送信息,顾客在某个日期下了订单,并指定了一个期望的配送日期(和下单日期相同或者在那之后)。

如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。 「首次订单」是顾客最早创建的订单。我们保证一个顾客只会有一个「首次订单」。 编写解决方案以获取即时订单在所有用户的首次订单中的比例。保留两位小数。

2 测试用例

输入:

Delivery 表:

+-------------+-------------+------------+-----------------------------+
| delivery_id | customer_id | order_date | customer_pref_delivery_date |
+-------------+-------------+------------+-----------------------------+
| 1           | 1           | 2019-08-01 | 2019-08-02                  |
| 2           | 2           | 2019-08-02 | 2019-08-02                  |
| 3           | 1           | 2019-08-11 | 2019-08-12                  |
| 4           | 3           | 2019-08-24 | 2019-08-24                  |
| 5           | 3           | 2019-08-21 | 2019-08-22                  |
| 6           | 2           | 2019-08-11 | 2019-08-13                  |
| 7           | 4           | 2019-08-09 | 2019-08-09                  |
+-------------+-------------+------------+-----------------------------+

输出:

+----------------------+
| immediate_percentage |
+----------------------+
| 50.00                |
+----------------------+

解释: 1 号顾客的 1 号订单是首次订单,并且是计划订单。 2 号顾客的 2 号订单是首次订单,并且是即时订单。 3 号顾客的 5 号订单是首次订单,并且是计划订单。 4 号顾客的 7 号订单是首次订单,并且是即时订单。 因此,一半顾客的首次订单是即时的。

3 解题思路

  1. customer_id分组,按照日期先后进行排名,找出每个customer_id排名第一的数据,即首次订单
select customer_id,  
	 order_date,  
	 customer_pref_delivery_date,  
	 rank() over (partition by customer_id order by order_date asc) as rk  
from Delivery

执行结果

+-----------+----------+---------------------------+--+
|customer_id|order_date|customer_pref_delivery_date|rk|
+-----------+----------+---------------------------+--+
|1          |2019-08-01|2019-08-02                 |1 |
|1          |2019-08-11|2019-08-12                 |2 |
|2          |2019-08-02|2019-08-02                 |1 |
|2          |2019-08-11|2019-08-13                 |2 |
|3          |2019-08-21|2019-08-22                 |1 |
|3          |2019-08-24|2019-08-24                 |2 |
|4          |2019-08-09|2019-08-09                 |1 |
+-----------+----------+---------------------------+--+
  1. 使用d.rk = 1筛选出每个customer_id排名第一的数据,分别统计首次订单数量count(d.customer_id)和首次订单中即时订单数量sum(if(d.order_date = d.customer_pref_delivery_date, 1, 0)),计算占比并保留两位小数
select round(sum(if(d.order_date = d.customer_pref_delivery_date, 1, 0)) * 100  
                 / count(d.customer_id), 2) as immediate_percentage  
from (select customer_id,  
             order_date,  
             customer_pref_delivery_date,  
             rank() over (partition by customer_id order by order_date asc) as rk  
      from Delivery) as d  
where d.rk = 1;

执行结果

+--------------------+
|immediate_percentage|
+--------------------+
|50.00               |
+--------------------+