MySQL查询:按车辆ID和清洁类型分组获取最新清洁日期
解决cleanings表中按车辆和清洁类型取最新记录的问题
你的原SQL语句存在两个核心问题:
- 使用
GROUP BY vehicle_id, type后直接SELECT *,不符合SQL标准(仅MySQL宽松模式允许),此时返回的是分组内随机或最早的行,而非按ORDER BY date DESC筛选的最新行——因为ORDER BY是在分组完成后对结果集排序,不影响分组时的行选择逻辑。 - 没有明确指定取每组的最大日期对应的记录。
以下是几种可行的解决方案:
方法1:窗口函数(推荐,适用于MySQL 8.0+、PostgreSQL、SQL Server等)
利用ROW_NUMBER()窗口函数,按vehicle_id和type分组,每组内按date降序排序,取排序后第一行(即最新记录):
SELECT id, vehicle_id, employees_id, type, date, created, modified FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY vehicle_id, type ORDER BY date DESC, id DESC) AS rn FROM cleanings ) t WHERE rn = 1 ORDER BY vehicle_id ASC;
注:添加id DESC是为了在同一日期有多条记录时,取最新创建的那条(因为id通常自增),可根据实际需求调整排序字段。
方法2:子查询关联(兼容旧版本数据库如MySQL 5.x)
先通过子查询获取每个(vehicle_id, type)组合的最大清洁日期,再关联原表拿到对应完整记录:
SELECT c.* FROM cleanings c INNER JOIN ( SELECT vehicle_id, type, MAX(date) AS max_date FROM cleanings GROUP BY vehicle_id, type ) t ON c.vehicle_id = t.vehicle_id AND c.type = t.type AND c.date = t.max_date ORDER BY c.vehicle_id ASC;
注:如果同一(vehicle_id, type)在同一天有多条记录,此方法会返回所有当天的记录,若需仅保留一条,可额外添加id或created字段的筛选条件。
方法3:仅获取核心字段(如果不需要完整记录)
若只需vehicle_id、type和最新清洁日期,直接用聚合函数即可:
SELECT vehicle_id, type, MAX(date) AS latest_clean_date FROM cleanings GROUP BY vehicle_id, type ORDER BY vehicle_id ASC;
内容的提问来源于stack exchange,提问作者Ryflex
相关产品推荐
相关产品推荐

