如何按DISTANCE与STROKE_ID分组获取游泳最快TIME记录
问题:筛选每组距离与泳姿组合的最快游泳记录
我有一张扁平结构的数据表,包含以下字段:
- NAME:游泳者姓名
- DISTANCE:游泳距离
- STROKE_ID:泳姿ID
- TIME:游泳时间(浮点型)
需求:针对每一组DISTANCE与STROKE_ID的组合,筛选出对应**TIME值最小(最快)**的唯一记录。
示例数据
下表中加粗姓名的记录为需要返回的目标结果:
| NAME | DISTANCE | STROKE_ID | TIME |
|---|---|---|---|
| Susane Smith | 50 | 1 | 74.33 |
| Cassey Putnam | 50 | 1 | 107.24 |
| Kelly Maine | 50 | 1 | 118.08 |
| Susane Smith | 100 | 1 | 168.4 |
| Charlotte Castle | 200 | 1 | 476.46 |
| Susane Smith | 50 | 2 | 83.23 |
| Charlotte Castle | 50 | 2 | 104.83 |
| Katy Cooper | 50 | 2 | 167.49 |
| Susane Smith | 100 | 2 | 174.93 |
| Charlotte Castle | 100 | 2 | 219.29 |
| JoAnne Cooper | 100 | 2 | 355.74 |
| Maddy Franks | 200 | 2 | 377.15 |
| JoAnne Cooper | 200 | 2 | 733.77 |
| Charlotte Castle | 50 | 3 | 138.5 |
| Charlotte Castle | 100 | 3 | 349.2 |
| Charlotte Castle | 200 | 3 | 676.12 |
解决方案
方法1:窗口函数(推荐,支持MySQL 8+、PostgreSQL、SQL Server等)
利用ROW_NUMBER()窗口函数按分组排序,直接取每组的第一条最快记录:
SELECT NAME, DISTANCE, STROKE_ID, TIME FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY DISTANCE, STROKE_ID ORDER BY TIME ASC) AS rn FROM swimmers ) t WHERE rn = 1;
- 逻辑:
PARTITION BY按距离和泳姿分组,ORDER BY TIME ASC让每组内按时间从小到大排序,rn=1筛选出每组的最快记录。如果存在并列最快,该方法只会返回其中一条(按数据库默认规则排序)。
方法2:关联子查询(兼容旧版数据库)
先通过子查询找出每组的最小时间,再关联原表获取对应记录:
SELECT s.NAME, s.DISTANCE, s.STROKE_ID, s.TIME FROM swimmers s INNER JOIN ( SELECT DISTANCE, STROKE_ID, MIN(TIME) AS min_time FROM swimmers GROUP BY DISTANCE, STROKE_ID ) t ON s.DISTANCE = t.DISTANCE AND s.STROKE_ID = t.STROKE_ID AND s.TIME = t.min_time;
- 注意:如果同一组内有多个游泳者时间相同(并列最快),该方法会返回所有并列记录。
内容的提问来源于stack exchange,提问作者Bob T
相关产品推荐
相关产品推荐

