【场景】:在某个数据的基础上再计算、求单个和整体再合并

【分类】:in子查询、行合并

分析思路

难点:

1.确定取消订单记录的条件:当start_time is null表示订单记录取消

关键是理解业务

首先,搞清楚5个时间的业务关系

event_time-打车时间, end_time-打车结束时间, order_time-接单时间, start_time-开始计费的上车时间, finish_time-订单完成时间

(1)找到2021年10月有过取消订单记录的司机

  • [条件]:date(order_time) between '20211001' and '20211007' and city = '北京'
  • [使用]:group by driver_id having count(order_time) >= 3

(2)计算他们每人全部已完成的有评分订单的平均评分及总体平均评分,保留1位小数。先按driver_id升序输出,再输出总体情况

统计每人情况平均评分,按driver_id升序; 统计总体情况平均评分;再使用union合并行

  • [使用]:union

求解代码

方法一

with子句 + union

with
    main as(
        #找到2021年10月有过取消订单记录的司机
        select distinct
            driver_id
        from tb_get_car_order
        where start_time is null
        and date_format(order_time,'%Y%m') = '202110' 
    )
#计算他们每人全部已完成的有评分订单的平均评分及总体平均评分,保留1位小数。先按driver_id升序输出,再输出总体情况
(
    #统计每人情况平均评分,按driver_id升序
    select
        driver_id,
        round(avg(grade),1) as avg_grade
    from tb_get_car_order
    join main using(driver_id)
    group by driver_id
    order by driver_id
)
union
(
    #统计总体情况平均评分
    select
        '总体' as driver_id,
        round(avg(grade),1) as avg_grade
    from tb_get_car_order
    join main using(driver_id)
)

方法二

in子查询 + union

(
    #统计每人情况平均评分,按driver_id升序
    select
        driver_id,
        round(avg(grade),1) as avg_grade
    from tb_get_car_order
    where driver_id in(
        #找到2021年10月有过取消订单记录的司机
        select
            driver_id
        from tb_get_car_order
        where start_time is null
        and date_format(order_time,'%Y%m') = '202110' 
    )
    group by driver_id
    order by driver_id
)
union
(
    #统计总体情况平均评分
    select
        '总体' as driver_id,
        round(avg(grade),1) as avg_grade
    from tb_get_car_order
    where driver_id in(
        #找到2021年10月有过取消订单记录的司机
        select
            driver_id
        from tb_get_car_order
        where start_time is null
        and date_format(order_time,'%Y%m') = '202110' 
    )
)