美团大数据面试SQL-骑手接单量统计及排名
⚠️ 待修正
一、题目背景
这道题来自美团外卖配送部门的数据分析岗面试。美团有数百万注册骑手,骑手的接单量直接影响配送运力的利用率。统计每个骑手的日接单量和排名,是骑手绩效考核和调度优化的基础数据。
业务场景:骑手管理的核心指标是"日接单量"——太少说明该骑手利用率低,太多可能导致超时。区域调度员每天看骑手接单排名,对排名垫底的骑手做培训提醒,对排名靠前的骑手发放奖励。
二、题目
现有一张外卖订单表 t4_order_info,记录了每笔订单的骑手信息和接单时间。请统计每个骑手的日接单量及日排名。
外卖订单表 t4_order_info:
+----------+----------+---------------------+
| order_id | rider_id | order_time |
+----------+----------+---------------------+
| O001 | R01 | 2023-03-01 10:00:00 |
| O002 | R02 | 2023-03-01 10:30:00 |
| O003 | R01 | 2023-03-01 11:00:00 |
| O004 | R03 | 2023-03-01 11:30:00 |
| O005 | R01 | 2023-03-01 12:00:00 |
| O006 | R02 | 2023-03-01 12:30:00 |
| O007 | R01 | 2023-03-02 10:00:00 |
| O008 | R02 | 2023-03-02 10:30:00 |
| O009 | R02 | 2023-03-02 11:00:00 |
| O010 | R03 | 2023-03-02 11:30:00 |
| O011 | R03 | 2023-03-02 12:00:00 |
| O012 | R01 | 2023-03-02 12:30:00 |
+----------+----------+---------------------+
三、思路分析
本题考察分组聚合 + 窗口排名,是骑手绩效分析的基础题。
解题步骤:
- 提取日期
substr(order_time, 1, 10); - 按骑手+日期分组统计接单量;
- 使用 RANK() 按日期分组、按接单量降序排名;
| 维度 | 评分 |
|---|---|
| 题目难度 | ⭐️⭐️ |
| 题目清晰度 | ⭐️⭐️⭐️⭐️⭐️ |
| 业务常见度 | ⭐️⭐️⭐️⭐️⭐️ |
四、逐步推导
1. 按骑手+日期统计接单量
执行SQL
select rider_id,
substr(order_time, 1, 10) as order_date,
count(1) as order_cnt
from t4_order_info
group by rider_id, substr(order_time, 1, 10)
order by order_date, order_cnt desc
执行结果
+----------+-------------+-----------+
| rider_id | order_date | order_cnt |
+----------+-------------+-----------+
| R01 | 2023-03-01 | 3 |
| R02 | 2023-03-01 | 2 |
| R03 | 2023-03-01 | 1 |
| R01 | 2023-03-02 | 2 |
| R02 | 2023-03-02 | 2 |
| R03 | 2023-03-02 | 2 |
+----------+-------------+-----------+
2. 按日对骑手接单量排名
执行SQL
select rider_id,
order_date,
order_cnt,
rank() over (partition by order_date order by order_cnt desc) as daily_rank
from (
select rider_id,
substr(order_time, 1, 10) as order_date,
count(1) as order_cnt
from t4_order_info
group by rider_id, substr(order_time, 1, 10)
) t
order by order_date, daily_rank
执行结果
+----------+-------------+-----------+------------+
| rider_id | order_date | order_cnt | daily_rank |
+----------+-------------+-----------+------------+
| R01 | 2023-03-01 | 3 | 1 |
| R02 | 2023-03-01 | 2 | 2 |
| R03 | 2023-03-01 | 1 | 3 |
| R01 | 2023-03-02 | 2 | 1 |
| R02 | 2023-03-02 | 2 | 1 |
| R03 | 2023-03-02 | 2 | 1 |
+----------+-------------+-----------+------------+
3月1日R01以3单排名第一;3月2日三人均为2单并列第一。
五、常见坑点
坑1:日期提取方式影响性能
substr(order_time, 1, 10) 字符串截取和 date_format(order_time, 'yyyy-MM-dd') 效果相同,但 date_format 需要对字符串做日期解析,略慢。如果 order_time 已经是标准格式,用 substr 更高效。
坑2:RANK 并列时的排名展示
三人接单量都是2单时,RANK 返回 (1,1,1),DENSE_RANK 也返回 (1,1,1),ROW_NUMBER 则是 (1,2,3)。以"日排名"展示给骑手时,用 RANK 或 DENSE_RANK 更公平——同样接单量不应该被硬分出名次。
六、举一反三
- 按周/月汇总:GROUP BY rider_id + week/month,统计骑手周/月总接单量和平均日接单量
- 接单量+准时率综合排名:加权公式 = 接单量 × 0.5 + 准时率 × 0.5,综合评估骑手绩效
- 时段细分:按午高峰/晚高峰/非高峰时段分别统计,识别不同骑手的时段偏好和能力
- 新骑手爬坡分析:统计骑手注册后前30天的日接单量趋势,评估新骑手培训效果
七、知识点总结
| 考点 | 说明 |
|---|---|
| substr 提取日期 | 从完整时间戳截取日期部分用于按日分组 |
| GROUP BY rider_id + date | 按骑手和日期双维度聚合统计接单量 |
| RANK() OVER(PARTITION BY date) | 按日分组、按接单量降序排名 |
| 并列排名的选择 | RANK/DENSE_RANK/ROW_NUMBER 三种语义差异 |
八、建表语句和数据插入
点击展开 DDL & DML
CREATE TABLE t4_order_info (
order_id string COMMENT '订单ID',
rider_id string COMMENT '骑手ID',
order_time string COMMENT '接单时间'
) COMMENT '外卖订单表';
-- 数据插入
INSERT INTO t4_order_info VALUES
('O001', 'R01', '2023-03-01 10:00:00'),
('O002', 'R02', '2023-03-01 10:30:00'),
('O003', 'R01', '2023-03-01 11:00:00'),
('O004', 'R03', '2023-03-01 11:30:00'),
('O005', 'R01', '2023-03-01 12:00:00'),
('O006', 'R02', '2023-03-01 12:30:00'),
('O007', 'R01', '2023-03-02 10:00:00'),
('O008', 'R02', '2023-03-02 10:30:00'),
('O009', 'R02', '2023-03-02 11:00:00'),
('O010', 'R03', '2023-03-02 11:30:00'),
('O011', 'R03', '2023-03-02 12:00:00'),
('O012', 'R01', '2023-03-02 12:30:00');
📱关注公众号
「数据仓库技术」文章同步更新,不错过每一篇干货

💬加群交流
备注「数据仓库技术」加入社群,每日一道大厂SQL真题
