MySQL:按车辆分组计算首末捕获记录距离差值的总和
解决方案:计算车辆首次与最新捕获记录的距离差值之和
没问题,我来帮你解决这个问题。核心是要严格基于captured_at字段判断记录的先后(毕竟你提到ID大不一定代表最新),下面给你两种实用的MySQL实现方式:
方法一:兼容所有MySQL版本(子查询分组法)
这种写法不需要依赖高版本的窗口函数,适合所有MySQL版本。思路是先分别筛选出每个车辆的首次捕获记录(最小captured_at对应的距离)和最新捕获记录(最大captured_at对应的距离),再关联计算差值后求和:
SELECT SUM(u_last.distance - u_first.distance) AS total_distance_diff FROM ( -- 获取每个车辆的首次捕获距离 SELECT vehicle_id, distance FROM updates u WHERE captured_at = (SELECT MIN(captured_at) FROM updates WHERE vehicle_id = u.vehicle_id) ) u_first JOIN ( -- 获取每个车辆的最新捕获距离 SELECT vehicle_id, distance FROM updates u WHERE captured_at = (SELECT MAX(captured_at) FROM updates WHERE vehicle_id = u.vehicle_id) ) u_last ON u_first.vehicle_id = u_last.vehicle_id;
方法二:MySQL 8.0+ 推荐(窗口函数法)
如果你的MySQL版本是8.0及以上,用窗口函数会更简洁高效。这里用ROW_NUMBER()给每个车辆的记录按captured_at排序,筛选出首次和最新记录后计算差值:
WITH ranked_updates AS ( SELECT vehicle_id, distance, -- 按captured_at升序编号,1就是首次记录 ROW_NUMBER() OVER (PARTITION BY vehicle_id ORDER BY captured_at ASC) AS rn_asc, -- 按captured_at降序编号,1就是最新记录 ROW_NUMBER() OVER (PARTITION BY vehicle_id ORDER BY captured_at DESC) AS rn_desc FROM updates ) SELECT SUM(last.distance - first.distance) AS total_distance_diff FROM ranked_updates first JOIN ranked_updates last ON first.vehicle_id = last.vehicle_id WHERE first.rn_asc = 1 AND last.rn_desc = 1;
关键说明
- 两种方法都完全基于
captured_at的最小/最大值来判断首次和最新记录,不会受ID大小的影响,符合你的需求。 - 针对你给出的示例场景(比如车辆1的差值是100-50,车辆2是300-200),两种方法都会返回总和150,和预期一致。
内容的提问来源于stack exchange,提问作者Artem Kalinchuk
相关产品推荐
相关产品推荐

