作者:whisper
链接:http://proprogrammar.com:443/article/640
声明:请尊重原作者的劳动,如需转载请注明出处
配送表:
Delivery
+-----------------------------+---------+ | Column Name | Type | +-----------------------------+---------+ | delivery_id | int | | customer_id | int | | order_date | date | | customer_pref_delivery_date | date | +-----------------------------+---------+ delivery_id 是表的主键。 该表保存着顾客的食物配送信息,顾客在某个日期下了订单,并指定了一个期望的配送日期(和下单日期相同或者在那之后)。
如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。写一条 SQL 查询语句获取即时订单所占的比例, 保留两位小数。
查询结果如下所示:
Delivery 表: +-------------+-------------+------------+-----------------------------+ | delivery_id | customer_id | order_date | customer_pref_delivery_date | +-------------+-------------+------------+-----------------------------+ | 1 | 1 | 2019-08-01 | 2019-08-02 | | 2 | 5 | 2019-08-02 | 2019-08-02 | | 3 | 1 | 2019-08-11 | 2019-08-11 | | 4 | 3 | 2019-08-24 | 2019-08-26 | | 5 | 4 | 2019-08-21 | 2019-08-22 | | 6 | 2 | 2019-08-11 | 2019-08-13 | +-------------+-------------+------------+-----------------------------+ Result 表: +----------------------+ | immediate_percentage | +----------------------+ | 33.33 | +----------------------+ 2 和 3 号订单为即时订单,其他的为计划订单。
select round(sum(case when t.order_date = t.customer_pref_delivery_date then 1 else 0 end) * 100 / count(1), 2) immediate_percentage
from Delivery t
sum嵌套case,求出下单日期与配送日期相同条件下的记录数,学一下sum+case组合的用法,外层还嵌套了round
配送表:
Delivery
+-----------------------------+---------+ | Column Name | Type | +-----------------------------+---------+ | delivery_id | int | | customer_id | int | | order_date | date | | customer_pref_delivery_date | date | +-----------------------------+---------+ delivery_id 是表的主键。 该表保存着顾客的食物配送信息,顾客在某个日期下了订单,并指定了一个期望的配送日期(和下单日期相同或者在那之后)。
如果顾客期望的配送日期和下单日期相同,则该订单称为 「即时订单」,否则称为「计划订单」。
「首次订单」是顾客最早创建的订单。我们保证一个顾客只会有一个「首次订单」。
写一条 SQL 查询语句获取即时订单在所有用户的首次订单中的比例。保留两位小数。
查询结果如下所示:
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 | +-------------+-------------+------------+-----------------------------+ Result 表: +----------------------+ | immediate_percentage | +----------------------+ | 50.00 | +----------------------+ 1 号顾客的 1 号订单是首次订单,并且是计划订单。 2 号顾客的 2 号订单是首次订单,并且是即时订单。 3 号顾客的 5 号订单是首次订单,并且是计划订单。 4 号顾客的 7 号订单是首次订单,并且是即时订单。 因此,一半顾客的首次订单是即时的。
select round(sum(case when t.order_date = t.customer_pref_delivery_date then 1 else 0 end) / count(1) * 100 , 2) immediate_percentage
from (
select customer_id, min(order_date) first_order
from Delivery
group by customer_id
) fo inner join Delivery t
on fo.first_order = t.order_date and fo.customer_id = t.customer_id
同样是round+sum+case的形式,在上题基础上限制了是首次订单,所以先查出首次订单,再做连接,学一下group by + 聚集函数与连接的用法(连接条件)
下面看另一种做法
select
round(sum(if(b.mo=b.mc,1,0))*100/count(b.mc),2) as immediate_percentage
from
(select min(order_date)as mo,min(customer_pref_delivery_date)as mc
from Delivery
group by customer_id)b
这里就充分运用了group by + 聚集函数,省去了连接,而且用sum + if(两分支)代替了sum + case(多分支),更细致一些
亲爱的读者:有时间可以点赞评论一下
全部评论