模拟某打车公司的业务题:分析打车的业务问题

某打车公司业务题:分析打车业务问题

公司A是的app(类似滴滴、uber)为用户提供打车服务。现有四张表(模拟数据),分别是driver(司机数据)表,online_time(在线时长数据)表,order_info(订单数据)表,city(城市匹配数据)表。

现有如下业务问题:

  1. 提取2020年8月各城市每天的司机数、快车订单量和快车流水数据。

  2. 提取2020年8月和9月,每个月的北京市新老司机(首单日期在当月为新司机)的司机数、在线时长和TPH(订单量/在线时长)数据。

  3. 分别提取司机数大于20,司机总在线时长大于2小时,订单量大于1,乘客数大于1的城市名称数据。

1.熟悉各表数据

(1)diver(司机数据)表

在这里插入图片描述
(2)online_time(在线时长数据)表
在这里插入图片描述
(3)order_info(订单数据)表
在这里插入图片描述

  表中 “产品线id”中的数字分别表示不同的含义:1代表的是专车,2代表的是企业,3代表的是快车,4代表的是企业快车。

(4)city(城市匹配数据)表
在这里插入图片描述

2.解决各业务问题

2.1 提取2020年8月各城市每天的司机数、快车订单量和快车流水数据

1.提取2020年8月各城市每天的司机数

  解题思路:(1)限定时间在2020年8月,可以使用between and;(2)各城市每天是按照城市和日期进行分组;(3)司机数是使用count(distinct 司机id)来计数,如果司机id是主键的话,可以不使用distinct。最终答案如下:

SELECT b.城市名称,a.日期,count(DISTINCT 司机id) as 司机数
FROM driver as a
LEFT JOIN city as b on a.城市id=b.城市id
WHERE 日期 BETWEEN '2020-08-01' and '2020-08-31'
GROUP BY a.城市id, a.日期;

  部分查询结果如下:
在这里插入图片描述

2.提取2020年8月各城市每天的快车订单量

  解题思路:(1)时间限定和前面的一样,也可以使用date_format来限定日期;(2)快车,则需要从产品线id中提取出代表快车的编号,如前面说的,3代表快车,可以使用where来限定id=3;(3)订单量根据订单id进行计算。答案如下:

SELECT c.城市名称,a.日期,COUNT(DISTINCT 订单id) as 订单量
FROM order_info as a
LEFT JOIN driver as b on a.司机id=b.司机id
LEFT JOIN city as c on b.城市id=c.城市id
WHERE 产品线id='3' and DATE_FORMAT(a.日期,'%Y-%m')='2020-08'
GROUP BY b.城市id,a.日期;

  结果如下:
在这里插入图片描述

3.提取2020年8月各城市每天的快车流水数据

  解题思路:(1)大部分解题思路和前面一样,有变化的是流水数据,流水数据是需要使用sum来进行计算得到的。答案如下:

SELECT c.城市名称,a.日期,SUM(流水) as 流水数据
FROM order_info as a
LEFT JOIN driver as b on a.司机id=b.司机id
LEFT JOIN city as c on b.城市id=c.城市id
WHERE 产品线id='3' and DATE_FORMAT(a.日期,'%Y-%m')='2020-08'
GROUP BY b.城市id,a.日期;

  结果如下:
在这里插入图片描述

2.2 提取2020年8月和9月,每个月的北京市新老司机(首单日期在当月为新司机)的司机数、在线时长和TPH(订单量/在线时长)数据

1.提取2020年8月和9月,每个月的北京市新老司机(首单日期在当月为新司机)的司机数

  解题思路:(1)提取2020年8月和9月的,则可以使用or来判断,或者使用union连接都可以,先分别查出8月和9月的数据,再进行联结;(2)将地点限定为北京市,则使用where条件;(3)首单日期在当月的为新司机,说明分别在首单完成日期分别在8月份或者9月份的视为首单日期,则可以直接使用“首单完成日期”=8月或者9月。答案如下:

SELECT DATE_FORMAT(a.日期,'%Y-%m'),COUNT(DISTINCT a.司机id) as '司机数'
FROM driver as a
LEFT JOIN city as b on a.城市id=b.城市id
WHERE b.城市名称='北京' AND DATE_FORMAT(a.首次完成订单时间,'%Y-%m')='2020-08'
	  AND a.`日期` BETWEEN '2020-08-01' and '2020-09-31'
GROUP BY DATE_FORMAT(a.日期,'%Y-%m')

UNION

SELECT DATE_FORMAT(a.日期,'%Y-%m'),COUNT(DISTINCT a.司机id) as '司机数'
FROM driver as a
LEFT JOIN city as b on a.城市id=b.城市id
WHERE b.城市名称='北京' AND DATE_FORMAT(a.首次完成订单时间,'%Y-%m')='2020-09'
	  AND a.`日期` BETWEEN '2020-08-01' and '2020-09-31'
GROUP BY DATE_FORMAT(a.日期,'%Y-%m')

  结果如下:
在这里插入图片描述

2.提取2020年8月和9月,每个月的北京市新司机的在线时长

  解题思路:(1)提取2020年8月和9月的,则可以使用or来判断;(2)将地点限定为北京市,则使用where条件;(3)首单日期在当月的为新司机,说明分别在首单完成日期分别在8月份或者9月份的视为首单日期。答案如下:

SELECT DATE_FORMAT(a.日期,'%Y-%m'), a.司机id, SUM(在线时长) as '在线时长'
FROM online_time as a
LEFT JOIN driver as b on a.司机id=b.司机id
LEFT JOIN city as c on b.城市id=c.城市id
WHERE c.城市名称='北京' and (b.首次完成订单时间 BETWEEN '2020-08-01' and '2020-08-31'
      OR b.首次完成订单时间 BETWEEN '2020-09-01' and '2020-09-31')
			AND a.日期 BETWEEN '2020-08-01' and '2020-09-31'
GROUP BY DATE_FORMAT(a.日期,'%Y-%m')

  结果如下:
在这里插入图片描述
3.提取2020年8月和9月,每个月的北京市新司机的TPH(订单量/在线时长)

  解题思路:和前面的类似,还需计算出新司机的订单量。答案如下:

SELECT t.日期, t.订单量/t.在线时长 as '新司机的TPH'
FROM
(SELECT DATE_FORMAT(a.日期,'%Y-%m') as '日期', COUNT(DISTINCT d.订单id) as '订单量',SUM(在线时长) as '在线时长'
FROM online_time as a
LEFT JOIN driver as b on a.司机id=b.司机id
LEFT JOIN city as c on b.城市id=c.城市id
LEFT JOIN order_info as d on a.司机id=d.司机id
WHERE c.城市名称='北京' and (b.首次完成订单时间 BETWEEN '2020-08-01' and '2020-08-31'
      OR b.首次完成订单时间 BETWEEN '2020-09-01' and '2020-09-31')
			AND a.日期 BETWEEN '2020-08-01' and '2020-09-31'
GROUP BY DATE_FORMAT(a.日期,'%Y-%m')
) as t

  查询结果如下:
在这里插入图片描述

2.3 分别提取司机数大于20,司机总在线时长大于2小时,订单量大于1,乘客数大于1的城市名称数据

1.司机数大于20的城市名称

  解题思路:(1)司机数大于20,可以直接使用count()>20;(2)按照城市名称进行分组。答案如下:

SELECT b.`城市名称`,COUNT(DISTINCT a.司机id) as '司机数'
FROM driver as a
LEFT JOIN city as b on a.`城市id`=b.`城市id`
GROUP BY b.`城市名称`
HAVING COUNT(DISTINCT a.司机id)>20;

  结果如下:
在这里插入图片描述

2.查询各司机总在线时长大于2小时的城市名称,司机id和总在线时长

  解题思路:(1)司机总在线时长大于2小时,可以直接使用sum()>2;(2)按照司机id进行分组。答案如下:

SELECT c.`城市名称`,a.`司机id`,a.总在线时长
FROM
(SELECT 司机id,SUM(在线时长) as '总在线时长'
FROM online_time
GROUP BY 司机id
HAVING SUM(在线时长)>2) as a
LEFT JOIN driver as b on a.`司机id`=b.`司机id`
LEFT JOIN city as c on b.`城市id`=c.`城市id`;

  部分查询结果如下:
在这里插入图片描述

3.查询各司机订单量大于1的城市名称,司机id,订单量

  解题思路:先根据司机id查询出订单量大于1的司机id,然后再连接另外两张表。

SELECT c.`城市名称`,a.`司机id`,a.订单量
FROM
(SELECT 司机id,COUNT(DISTINCT 订单id) as '订单量'
FROM order_info 
GROUP BY 司机id
HAVING COUNT(DISTINCT 订单id)>1) as a
LEFT JOIN driver as b on a.`司机id`=b.`司机id`
LEFT JOIN city as c on b.`城市id`=c.`城市id`;

  查询结果如下:
在这里插入图片描述
4.查询出每位司机所载的乘客数大于1的司机id,乘客数以及所在的城市名称

  解题思路和前面的类似

SELECT a.`司机id`,a.乘客数,c.`城市名称`
FROM
(SELECT 司机id,COUNT(DISTINCT 乘客id) as 乘客数
FROM order_info
GROUP BY 司机id
HAVING COUNT(DISTINCT 乘客id)>1) as a
LEFT JOIN driver as b on a.`司机id`=b.`司机id`
LEFT JOIN city as c on b.`城市id`=c.`城市id`;

  查询结果如下:
在这里插入图片描述
  总结:该例子是根据某个公众号发的数据和他的业务需求进行整理的,可能与公众号的解题思路不太一样。文章中若有写错的地方,或者可以优化的地方,希望大家能帮我指出来,大家一起努力,一起进步呀!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章