首页 > 试题广场 >

2021年国庆在北京接单3次及以上的司机统计信息

[编程题]2021年国庆在北京接单3次及以上的司机统计信息
  • 热度指数:83109 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

用户打车记录表tb_get_car_record


(uid-用户ID, city-城市, event_time-打车时间, end_time-打车结束时间, order_id-订单号)


打车订单表tb_get_car_order

(order_id-订单号, uid-用户ID, driver_id-司机ID, order_time-接单时间, start_time-开始计费的上车时间,  finish_time-订单完成时间, mileage-行驶里程数, fare-费用, grade-评分)


场景逻辑说明
  • 用户提交打车请求后,在用户打车记录表生成一条打车记录,order_id-订单号设为null

  • 当有司机接单时,在打车订单表生成一条订单,填充order_time-接单时间及其左边的字段,start_time-开始计费的上车时间及其右边的字段全部为null,并把order_id-订单号order_time-接单时间end_time-打车结束时间)写入打车记录表;若一直无司机接单,超时或中途用户主动取消打车,则记录end_time-打车结束时间

  • 若乘客上车前,乘客或司机点击取消订单,会将打车订单表对应订单的finish_time-订单完成时间填充为取消时间,其余字段设为null

  • 当司机接上乘客时,填充订单表中该start_time-开始计费的上车时间
  • 当订单完成时填充订单完成时间、里程数、费用;评分设为null,在用户给司机打1~5星评价后填充。


问题:请统计2021年国庆7天期间在北京市接单至少3次的司机的平均接单数和平均兼职收入(暂不考虑平台佣金,直接计算完成的订单费用总额),结果保留3位小数。

输出示例
示例数据的输出结果如下

解释:
2021年国庆期间北京市的订单中,202共接了3单,兼职收入105;203接了4单,兼职收入137;201共接了1单,但取消了; 接单至少3次的司机有202和203,他两人全部总共接单数为7,总收入为242。因此平均接单数为3.500,平均收入为121.000;
示例1

输入

DROP TABLE IF EXISTS tb_get_car_record,tb_get_car_order;
CREATE TABLE tb_get_car_record (
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    uid INT NOT NULL COMMENT '用户ID',
    city VARCHAR(10) NOT NULL COMMENT '城市',
    event_time datetime COMMENT '打车时间',
    end_time datetime COMMENT '打车结束时间',
    order_id INT COMMENT '订单号'
) CHARACTER SET utf8 COLLATE utf8_bin;

CREATE TABLE tb_get_car_order (
    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    order_id INT NOT NULL COMMENT '订单号',
    uid INT NOT NULL COMMENT '用户ID',
    driver_id INT NOT NULL COMMENT '司机ID',
    order_time datetime COMMENT '接单时间',
    start_time datetime COMMENT '开始计费的上车时间',
    finish_time datetime COMMENT '订单结束时间',
    mileage DOUBLE COMMENT '行驶里程数',
    fare DOUBLE COMMENT '费用',
    grade TINYINT COMMENT '评分'
) CHARACTER SET utf8 COLLATE utf8_bin;

INSERT INTO tb_get_car_record(uid, city, event_time, end_time, order_id) VALUES
 (101, '北京', '2021-10-01 07:00:00', '2021-10-01 07:02:00', null),
 (102, '北京', '2021-10-01 09:00:30', '2021-10-01 09:01:00', 9001),
 (101, '北京', '2021-10-01 08:28:10', '2021-10-01 08:30:00', 9002),
 (103, '北京', '2021-10-02 07:59:00', '2021-10-02 08:01:00', 9003),
 (104, '北京', '2021-10-03 07:59:20', '2021-10-03 08:01:00', 9004),
 (105, '北京', '2021-10-01 08:00:00', '2021-10-01 08:02:10', 9005),
 (106, '北京', '2021-10-01 17:58:00', '2021-10-01 18:01:00', 9006),
 (107, '北京', '2021-10-02 11:00:00', '2021-10-02 11:01:00', 9007),
 (108, '北京', '2021-10-02 21:00:00', '2021-10-02 21:01:00', 9008) ;

INSERT INTO tb_get_car_order(order_id, uid, driver_id, order_time, start_time, finish_time, mileage, fare, grade) VALUES
 (9002, 101, 201, '2021-10-01 08:30:00', null, '2021-10-01 08:31:00', null, null, null),
 (9001, 102, 202, '2021-10-01 09:01:00', '2021-10-01 09:06:00', '2021-10-01 09:31:00', 10.0, 41.5, 5),
 (9003, 103, 202, '2021-10-02 08:01:00', '2021-10-02 08:15:00', '2021-10-02 08:31:00', 11.0, 41.5, 4),
 (9004, 104, 202, '2021-10-03 08:01:00', '2021-10-03 08:13:00', '2021-10-03 08:31:00', 7.5, 22, 4),
 (9005, 105, 203, '2021-10-01 08:02:10', '2021-10-01 08:18:00', '2021-10-01 08:31:00', 15.0, 44, 5),
 (9006, 106, 203, '2021-10-01 18:01:00', '2021-10-01 18:09:00', '2021-10-01 18:31:00', 8.0, 25, 5),
 (9007, 107, 203, '2021-10-02 11:01:00', '2021-10-02 11:07:00', '2021-10-02 11:31:00', 9.9, 30, 5),
 (9008, 108, 203, '2021-10-02 21:01:00', '2021-10-02 21:10:00', '2021-10-02 21:31:00', 13.2, 38, 4);

输出

北京|3.500|121.000
为什么,这个会错啊。代码和报错如下:


发表于 2025-04-17 18:37:15 回复(0)
select r.city city,round(count(o.driver_id)/count(distinct o.driver_id),3) avg_order_num,sum(o.fare)/count(distinct o.driver_id) avg_income
from tb_get_car_record r right join tb_get_car_order o
on r.order_id=o.order_id
where city='北京' and (date_format(finish_time,'%m%d') between '1001' and '1007')  
group by r.city
having count(o.order_id)>=3
为什么这个代码分开计算是对的,合起来计算就不对了
发表于 2025-02-20 22:18:47 回复(0)
select
city,round(avg(cnt),3),round(avg(cn),3)
from(
select
city,count(a.order_id) cnt,sum(fare) cn
from tb_get_car_order a
inner join tb_get_car_record b using(order_id)
where date(order_time)between '2021-10-01' and
'2021-10-07'
and city='北京'
group by city,driver_id
having count(*)>=3
)t
group by city
发表于 2024-09-02 15:54:07 回复(0)
with order_detail as(
    select t1.order_id,t1.uid,t1.driver_id,t1.order_time,t1.fare,
    t2.city
    from tb_get_car_order t1 left join tb_get_car_record t2
    on t1.order_id = t2.order_id
)
,driver_list as(
select driver_id
from order_detail
where city = '北京'
and date(order_time) between '2021-10-01' and '2021-10-07'
group by driver_id
having count(order_id) >= 3)

select 
    city,
    round(count(order_id)/count(distinct driver_id),3) as avg_order_num,
    round(sum(fare)/count(distinct driver_id),3) as avg_income
from order_detail
where driver_id in (select driver_id from driver_list)
and date(order_time) between '2021-10-01' and '2021-10-07'
and city = '北京'
group by city

发表于 2024-04-14 10:39:15 回复(0)
select city,
        round(count(order_id)/count(distinct(driver_id)) ,3) as avg_order_num,
        sum(fare)/count(distinct(driver_id)) as avg_income
from tb_get_car_order
left join tb_get_car_record using(order_id)
where city='北京'  and driver_id in (select driver_id
                                    from tb_get_car_order
                                    group by driver_id
                                    having count(order_id)>=3)
        and  DATE(order_time) BETWEEN '2021-10-01' AND '2021-10-07'
    求问大佬,为什么这个测试能过,提交输出的结果是错的呢?实际输出
北京
2.500
81.500

发表于 2024-03-11 16:04:42 回复(0)
with
t as( #总表
select city, driver_id as did, order_time, fare
from tb_get_car_record as t1
inner join tb_get_car_order as t2 using(order_id) 
where city='北京' and date(order_time) between '2021-10-01' and '2021-10-07'
),
t1 as ( # 接单数大于2次的司机和收入
select city, did, count(order_time) as cnt,  sum(fare) as income
from t
group by city, did
having cnt>2
)

select city, 
    round(avg(cnt), 3), 
    round(sum(income)/count(distinct did), 3)
from t1
group by city

发表于 2024-02-12 20:57:59 回复(0)
SELECT
city,
	ROUND(COUNT(tbo.order_id)/COUNT(DISTINCT driver_id),3) avg_order_num,
	ROUND(SUM(fare)/COUNT(DISTINCT driver_id),3) avg_income
	FROM tb_get_car_order tbo JOIN tb_get_car_record tbr ON tbo.`order_id`=tbr.`order_id`
WHERE city='北京'  AND DATE(order_time) BETWEEN '2021-10-01' AND '2021-10-07' AND driver_id IN (
SELECT driver_id FROM tb_get_car_order tbo JOIN tb_get_car_record tbr USING(order_id) WHERE DATE(order_time) BETWEEN '2021-10-01' AND '2021-10-07'
AND city='北京'
GROUP BY driver_id HAVING COUNT(order_id)>=3 
) GROUP BY city;
我服了,这个题目做了好久,主要原因是提交时只能对一半的测试用例。这里有两点需要注意:
1、只需要两表join就可以计算,直接计算总的订单用count就行,取消的订单也计算在内;
2、筛选条件一定要写全,最容易错的是订单数>=3的司机,这里我用的是一个子查询,而且子查询中必须也要join,因为要筛选出北京市。
发表于 2023-12-21 23:09:15 回复(0)
select city
    ,round(avg(order_num),3) avg_order_num
    ,avg(sum_fare) avg_income
from(
    select city
        ,driver_id
        ,sum(fare) sum_fare
        ,count(order_time) order_num
    from tb_get_car_record
    left join tb_get_car_order
    using(order_id)
    where city = '北京'
    and order_time between '2021-10-01' and '2021-10-07'
    group by city
        ,driver_id
    having count(order_time) >= 3
) a
group by city

发表于 2023-11-28 09:32:27 回复(0)
select distinct
    city,
    round(avg(count(order_time)) over(),3) avg_order_num,
    round(avg(sum(fare)) over(),3) avg_income
from tb_get_car_record t1
join tb_get_car_order t2
on t1.order_id = t2.order_id
where date(order_time) between '2021-10-01' and '2021-10-07'
and city = '北京'
group by city,driver_id
having count(order_time) >= 3;

发表于 2023-11-05 21:51:22 回复(0)
select city,round(sum(order_cnt)/count(driver_id),3) as avg_order_num,round(sum(fare_sum)/count(driver_id),3) as avg_income
from(
    select city,driver_id,count(order_id) as order_cnt,sum(fare) as fare_sum
    from(
        select
            b.city, -- 城市
            a.order_id, -- 订单号
            a.driver_id, -- 司机
            date(a.order_time) as order_date,
            a.fare -- 费用
        from
            tb_get_car_order a
            left join tb_get_car_record b on a.order_id = b.order_id
        where b.city='北京'
    ) t
    where order_date between '2021-10-01' and '2021-10-07'
    group by 1,2
    having order_cnt>=3
) a
group by 1

发表于 2023-10-18 20:40:17 回复(0)
with cte as(
select driver_id,count(order_id) as num,sum(fare) as income 
from tb_get_car_order a left join tb_get_car_record b using(order_id)
where city='北京' and date(order_time) between '2021-10-01' and  '2021-10-07'   # 如果中途取消的不算,则只需将 date(order_time) 改为date(start_time)
group by driver_id
having num>=3   )
select '北京' as city,round(avg(num),3) as avg_order_num,round(avg(income),3) as avg_income
from cte  

发表于 2023-10-07 17:07:24 回复(0)
select city, round(sum(num)/count(*),3) as avg_order_num,round(avg(s),3) as avg_income
from(
    select city, driver_id,count(order_time) as num, sum(fare) as s
 from tb_get_car_record u inner join tb_get_car_order d on u.order_id=d.order_id where order_time between '2021-10-01' and '2021-10-07' and u.city='北京'
 group by city,driver_id
) c where num>=3 group by city;
感谢评论区老哥,取消了也算接单,之前写sum(if(start_time is null, 0,1)) as num 提交第二个用例报错了
发表于 2023-08-25 13:48:05 回复(0)
球大佬们帮我看看是哪里的问题???
SELECT
	city,
	ROUND( COUNT( 1 ) / COUNT( DISTINCT driver_id ), 3 ) avg_order_num,
	ROUND( SUM( fare ) / COUNT( DISTINCT driver_id ), 3 ) avg_income 
FROM
	(
	SELECT
		t1.driver_id,
		t1.order_id,
		t1.fare,
		t2.event_time,
		t2.end_time,
		t2.city 
	FROM
		tb_get_car_order t1
		JOIN tb_get_car_record t2 ON t1.order_id = t2.order_id 
	WHERE
		t2.city = "北京" 
		AND t1.driver_id IN (
		SELECT
			driver_id 
		FROM
			( SELECT driver_id FROM tb_get_car_order WHERE mileage > 0 AND DATE_FORMAT( order_time, "%Y-%m-%d" ) BETWEEN "2021-10-01" AND "2021-10-07" ) t1 
		GROUP BY
			driver_id 
		HAVING
			COUNT( 1 ) >= 3 
		) 
	) tmp;
	


发表于 2023-08-09 22:14:04 回复(0)
select 
    city, 
    ROUND(AVG(order_num), 3) as avg_order_num,
    ROUND(AVG(income), 3) as avg_income
from (
select
city,
driver_id,
row_number() over(partition by driver_id order by  t.order_time desc) as rn,
count(t.order_id) over(partition by driver_id  ) as order_num,
sum(fare) over(partition by driver_id  ) as income
from tb_get_car_order t 
inner join tb_get_car_record p 
on t.order_id=p.order_id 
and p.city='北京'
where datediff('2021-10-07',date(t.order_time)) between 0 and 6
) tt 
where order_num>=3 and rn=1

发表于 2023-08-09 14:52:48 回复(1)
select city,round(avg(order_count),3) as avg_order_num,
round(avg(sum_fare),3) as avg_income
from(select city,count(order_time) as order_count,sum(fare) as sum_fare
from tb_get_car_record
join tb_get_car_order using(order_id)
where date_format(order_time,'%Y-%m-%d') between '2021-10-01' and '2021-10-07' and city="北京"
group by driver_id)t0
where sum_fare is not null and order_count>=3
group by city

发表于 2023-07-13 13:54:04 回复(0)
select
    city,
    round(avg(order_num), 3) avg_order_num,
    round(avg(income), 3) as avg_income
from
    (
        select
            r.city,
            count(o.order_id) as order_num,
            sum(o.fare) as income
        from
            tb_get_car_order as o
            inner join tb_get_car_record as r on o.order_id = r.order_id
        where
            date (o.order_time) between '2021-10-01' and '2021-10-07' and city = '北京'
        group by
            o.driver_id,
            r.city
        having
           order_num >= 3
    ) as subquery
group by
    city;


发表于 2023-05-22 17:40:25 回复(0)