SQL174 2021年国庆在北京接单3次及以上的司机统计信息
select
city,
round(avg(order_cnt),3) as avg_order_num,
round(avg(fare_cnt),3) as avg_income
from(
select
city,
driver_id,
count(order_id) as order_cnt,
sum(fare) as fare_cnt
from tb_get_car_order
join tb_get_car_record using(order_id)
where date(order_time) between '2021-10-1' and '2021-10-7'
and city='北京'
group by driver_id
having count(order_id)>=3
) as a
group by city
SQL175 有取消订单记录的司机平均评分
(
select
driver_id,
round(avg(grade),1) as avg_grade
from tb_get_car_order
join tb_get_car_record using(order_id)
where start_time is not null
and driver_id in (
select distinct driver_id
from tb_get_car_order
where start_time is NULL
and date_format(order_time,'%Y-%m')='2021-10')
group by driver_id
order by driver_id
)
union all
(
select
'总体' as driver_id,
round(avg(grade),1) as avg_grade
from tb_get_car_order
join tb_get_car_record using(order_id)
where start_time is not null
and driver_id in (
select distinct driver_id
from tb_get_car_order
where start_time is NULL
and date_format(order_time,'%Y-%m')='2021-10')
)
SQL176 每个城市中评分最高的司机信息
select
city,
driver_id,
avg_grade,
avg_order_num,
avg_mileage
from (
select
city,
driver_id,
avg_grade,
avg_order_num,
avg_mileage,
dense_rank() over(partition by city order by avg_grade desc) as rank_grade
from (
select
city,
driver_id,
round(avg(grade),1)avg_grade,
round(count(order_id)/count(distinct date_format(order_time,"%Y-%m-%d")),1) as avg_order_num,
round(sum(mileage)/count(distinct date_format(order_time,"%Y-%m-%d")),3) as avg_mileage
from tb_get_car_order
left join tb_get_car_record using(order_id)
group by city,driver_id
)as a
)as b
where rank_grade=1
order by avg_order_num
SQL177 国庆期间近7日日均取消订单量
select distinct date(order_time) dt,
round(
(select count(date(start_time))
from tb_get_car_order t2
where timestampdiff(day,date(order_time),date(t1.order_time)) between 0 and 6)/7
,2) as finish_num_7d,
round(
(select sum(if(start_time is null,1,0))
from tb_get_car_order t3
where timestampdiff(day,date(order_time),date(t1.order_time)) between 0 and 6)/7
,2) as cancel_num_7d
from tb_get_car_order t1
where date(order_time) between '2021-10-01' and '2021-10-03'
order by dt
select *
from (
select dt,
round(sum(finish_num) over (order by dt rows 6 preceding)/7,2) finish_num_7d,
round(sum(cancel_num) over (order by dt rows 6 preceding)/7,2) cancel_num_7d
from (
select distinct date(order_time) as dt,
count(start_time) as finish_num,
sum(if(start_time is null,1,0)) as cancel_num
from tb_get_car_order
group by dt
) t1
) t2
where dt between '2021-10-01' and '2021-10-03'
order by dt
SQL178 工作日各时段叫车量、等待接单时间和调整时间
select
(case when time(event_time)>='07:00:00' and time(event_time)<='09:00:00' then '早高峰'
when time(event_time)>='09:00:00' and time(event_time)<='17:00:00' then '工作时间'
when time(event_time)>='17:00:00' and time(event_time)<='20:00:00' then '晚高峰'
else '休息时间'
end ) as period,
count(order_time) as get_car_num,
round(avg(timestampdiff(second,event_time,order_time))/60,1) as avg_wait_time,
round(avg(timestampdiff(second,order_time,start_time))/60,1) as avg_dispatch_time
from tb_get_car_order
join tb_get_car_record using(order_id)
where weekday(event_time) between 0 and 4
group by period
order by get_car_num
SQL179 各城市最大同时等车人数
运用窗口函数对于不同城市的等车的人按照时间进行排序,得到同时等车人数,然后用max得到同时最多等车的人数。(窗口函数order by 具有累加的效果)
整个解题过程只要3个步骤:
首先,建立一张子表,对用户进入等车状态和离开等车状态进行定义后进行表并联;
接着,使用窗口函数对每个城市的等车状态进出uv进行累加,
最后,取出每个城市最大的UV即可。
用户分为以下三种状态:
状态1: 司机接单前取消,则没有生成order_id,这种情况,order_id IS NULL 记录end_time
状态2: 司机接单后取消,则没有上车时间,start_time IS NULL 记录 finish_time
状态3: 正常上车,记录start_time,start_time IS NOT NULL
状态2和3可以直接使用IFNULL()合并,IFNULL(start_time,finish_time) 如果start_time空则返回finish_time,不空则start_time (ifnull(表达式1,表达式2):如果表达式1为空则返回表达式2,不为空则返回表达式1)
定义完用户进入等车和离开等车这两种事件之后,关联所有表格,使用窗口函数排序累加即可。
以上的三种状态,进入状态记作UV=1,离开状态记作UV=-1,
题目要求 “ 如果同一时刻有人停止等车,有人开始等车,等车人数记作先增加后减少。” 所以,第三行窗口函数对uv也进行倒序排序。
with t1 as(
select city,
sum(uv)over(partition by city order by uv_time,uv desc) as uv_cnt #每个城市等车瞬时UV
from (
select city,
event_time uv_time,1 as uv
from tb_get_car_record #进入等车状态
union all
select city,end_time uv_time,-1 as uv
from tb_get_car_record
where order_id is null #接单前取消
union all
select city,
ifnull(start_time,finish_time) uv_time,-1 as uv
from tb_get_car_order
left join tb_get_car_record using(order_id)#接单后取消或上车
) as t
where date_format(uv_time,'%Y%m')='202110' #2021年10月
)
select city,max(uv_cnt) max_wait_uv
from t1
group by citY
order by max_wait_uv,citY;#排序先按照uv升序,uv一样按照城市升序