题解 | #每个城市中评分最高的司机信息#
每个城市中评分最高的司机信息
http://www.nowcoder.com/practice/dcc4adafd0fe41b5b2fc03ad6a4ac686
明确题意
- 统计每个城市中评分最高的司机平均评分(这里的意思是平均分最高的,刚开始误解题意了) ——保留1位小数
- 日均接单量————保留1位小数
- 日均行驶里程数————保留3位小数
- 有多个司机评分并列最高时,都输出
- 按日均接单数升序排序。
拆解题目
1. 将 tb_get_car_record 与 tb_get_car_order gco 左连
2. 分组之前要先筛选
- gcr.order_id IS NOT NULL一定要是接单之后,order_id如果为NULL只能说明打车了,但是司机并不一定接单!!!
- 筛选每个城市中平均分最高的司机的ID(这里我用的稍微复杂点,但是应该比较好理解)
SELECT driver_id
FROM (
SELECT
city,
driver_id,
dense_rank() over(PARTITION BY city ORDER BY avg_grade DESC) rk
# 用DENSE_RANK()主要是因为可能有多个第一
FROM (
SELECT
city,
driver_id,
AVG(grade) avg_grade
FROM tb_get_car_record gcr
LEFT JOIN tb_get_car_order gco
ON gcr.uid=gco.uid
GROUP BY city,driver_id
) city_order_avg -- 得到每个城市每个司机的平均得分
) city_order_avg_rank -- 得到每个城市每个司机平均得分排序
WHERE rk=1 -- 这里要筛选出平均分最高的司机
3. 计算各个指标
- 总的接单数: count(order_time)
- 总的里程数: COUNT(DISTINCT DATE(order_time))
- 总天数: SUM(IFNULL(mileage,0)
- 日均订单量=总的接单数/总天数
- 日均里程数=总的里程数/总天数
- 保留小数位数:ROUND(X,1/3)
- 按日均接单数升序排序:ORDER BY avg_order_num
代码
SELECT
city,
driver_id,
ROUND(AVG(grade),1) avg_grade,
ROUND(COUNT(order_time)/COUNT(DISTINCT DATE(order_time)),1) avg_order_num,
-- 总的接单数/总天数 【一天可能接多单,故要去重】
ROUND(SUM(IFNULL(mileage,0))/COUNT(DISTINCT DATE(order_time)),3) avg_mileage
-- 总的里程数/总天数
FROM tb_get_car_record gcr
LEFT JOIN tb_get_car_order gco
ON gcr.uid=gco.uid
WHERE driver_id IN
(
SELECT driver_id
FROM (
SELECT
city,
driver_id,
dense_rank() over(PARTITION BY city ORDER BY avg_grade DESC) rk
# 用DENSE_RANK()主要是因为可能有多个第一
FROM (
SELECT
city,
driver_id,
AVG(grade) avg_grade
FROM tb_get_car_record gcr
LEFT JOIN tb_get_car_order gco
ON gcr.uid=gco.uid
GROUP BY city,driver_id
) city_order_avg -- 得到每个城市每个司机的平均得分
) city_order_avg_rank -- 得到每个城市每个司机平均得分排序
WHERE rk=1 -- 这里要筛选出平均分最高的司机
) -- 这里是为了统计每个城市中平均分最高的司机的ID(注意读懂题意!!!)
AND gcr.order_id IS NOT NULL -- 一定要是接单之后,order_id如果为NULL只能说明打车了,但是司机并不一定接单!!!
GROUP BY city,driver_id
ORDER BY avg_order_num