题解 | #工作日各时段叫车量、等待接单时间和调度时间#

工作日各时段叫车量、等待接单时间和调度时间

http://www.nowcoder.com/practice/34f88f6d6dc549f6bc732eb2128aa338


一、知识点梳理和拓展

比较常规的知识点,涉及到星期的取值,我复习了下date_format,对时间换算的知识点,如下:

二、题目解读

统计周一到周五各时段的叫车量、平均等待接单时间和平均调度时间。
1)三个相关指标的定义
  • 叫车量:统计order_id。
  • 等待时间:从开始打车到司机接单,event_time和order_time的时间差,因而order_time不能为空。
  • 调度时间:从司机接单到上车,order_time和start_time的时间差,且订单状态为已完成订单,因而fare不能为空(fare不为空,start_time也肯定部为空)。
2)条件:周一到周五各时段
  • 各个时段用case when 来进行定义。
  • 周一到周五用date_format(字段名,‘%w’)来进行定义。
3)题目中隐藏的坑
这里有一个小坑,统计时间差要先以秒为单位统计,计算平均值的时候需要将秒转换成分(除以60)来计算。
3)字段需求
  • period:时间段划分
  • get_car_num:叫车量
  • avg_wait_time :平均等待时间
  • avg_dispatch_time :平均调度时间

三、解题步骤

梳理完了以后,发现整个解题步骤就2步:1)连接两张表建立一张子表:计算每个订单的等待时间和调度时间,并时间段进行赋值定义,并限定条件为周1到周5。2)建完表,通过对时间段进行聚类后,计算各个时段的叫车量和调度时间。

1)建立子表统计每一各订单的等待时间,调度时间,并对时间段进行定义
  • 等待时间
IF(order_time IS NOT NULL,TIMESTAMPDIFF(SECOND,event_time,order_time),NULL) wait_time, #计算叫车等待时间,order_time非空难
  • 调度时间
IF(fare IS NOT NULL,TIMESTAMPDIFF(SECOND,order_time,start_time),NULL) dispatch_time,#计算车辆调度时间,仅计算完成的订单,那么fare非空
  • 选择时间周1—周5
DATE_FORMAT(event_time,'%w') BETWEEN 1 AND 5; #周1到周5
  • 对时间段进行定义
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 period
2)对时间段进行聚类,求各时段的叫车量、平均等待接单时间和平均调度时间。结果按叫车量升序排序,平均等待接单时间和平均调度时间保留1位小数
  • 叫车量
COUNT(order_id) get_car_num
  • 平均等待时间和平均调度时间
ROUND(AVG(wait_time/60),1)avg_wait_time #平均等待时间
ROUND(AVG(dispatch_time/60),1)avg_dispatch_time #平均调度时间
  • 完整代码
WITH t1 AS(
SELECT  tb_get_car_record.order_id, #订单号用来计算叫车量
    IF(order_time IS NOT NULL,TIMESTAMPDIFF(SECOND,event_time,order_time),NULL) wait_time, #计算叫车等待时间,order_time非空难
    IF(fare IS NOT NULL,TIMESTAMPDIFF(SECOND,order_time,start_time),NULL) dispatch_time,#计算车辆调度时间,仅计算完成的订单,那么fare非空
	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 period
FROM tb_get_car_record LEFT JOIN tb_get_car_order USING(order_id)
WHERE DATE_FORMAT(event_time,'%w') BETWEEN 1 AND 5
)

SELECT period,COUNT(order_id)get_car_num,ROUND(AVG(wait_time/60),1)avg_wait_time , ROUND(AVG(dispatch_time/60),1)avg_dispatch_time
FROM t1 GROUP BY period ORDER BY get_car_num;
SQL解题集 文章被收录于专栏

这是牛客SQL相关的解题集

全部评论
我太天真了 我以为表数据全是周一到周五的 刚开始我也在想要不要搞这个 麻了!
1 回复 分享
发布于 2022-11-24 10:02 广东
交流几点:1.从场景出发,叫车量,应该是count(event_time),而不是count(order_id)。因为,当乘客叫车,未必有司机来接单,从而导致order_id为null。 2.等待时间直接timestampdiff(second,event_time,end_time),因而,不需要判断order_time是否为null,因为event_time与end_time是一定有值的。 3.调度时间timestampdiff(second,order_time,start_time),也不需要判断start_time是否为null,虽然答主这边是判断fare是否为null。假设start_time为null,则返回null,不参与avg()的计算,也就是说,在本题平均调度时间默认只计算了完成的订单。 个人观点哈
点赞 回复 分享
发布于 2022-05-07 19:09

相关推荐

评论
10
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务