SQLite按日期分组取最大时间对应行的TotalAcc最大值方法
错误原因
- 你当前使用的SQL不符合标准SQL规范:仅按
Date分组后直接选取TotalAcc、TotalProc这类非分组、非聚合字段时,SQLite会默认返回分组内的第一条匹配行,而非你需要的对应最大时间、最大TotalAcc的行。 - 直接调用
MAX(TotalAcc)返回错误值的核心原因是建表时TotalAcc字段定义为TEXT类型,直接做聚合会按字符串字典序排序,而非数值大小排序,因此会出现返回1290而非2222的问题。
正确查询写法
推荐写法(适配SQLite 3.25.0及以上版本,支持窗口函数)
用ROW_NUMBER()窗口函数实现分组排序取Top1,逻辑清晰易维护:
WITH ranked_data AS ( SELECT Date, Time, TotalAcc, TotalProc, -- 按日期分组,先按时间倒序,再将TotalAcc转成整数后倒序排序 ROW_NUMBER() OVER ( PARTITION BY Date ORDER BY Time DESC, CAST(TotalAcc AS INTEGER) DESC ) AS rn FROM table_name ) SELECT Date, TotalAcc, TotalProc, Time AS 最大Time FROM ranked_data WHERE rn = 1 ORDER BY Date DESC;
兼容低版本SQLite写法
如果使用的SQLite版本不支持窗口函数,可以用多层子查询关联实现:
SELECT t1.Date, t1.TotalAcc, t1.TotalProc, t1.Time AS 最大Time FROM table_name t1 -- 关联获取每个日期的最大时间 INNER JOIN ( SELECT Date, MAX(Time) AS max_time FROM table_name GROUP BY Date ) t2 ON t1.Date = t2.Date AND t1.Time = t2.max_time -- 关联获取每个日期+最大时间下的最大TotalAcc数值 INNER JOIN ( SELECT Date, Time, MAX(CAST(TotalAcc AS INTEGER)) AS max_total_acc FROM table_name GROUP BY Date, Time ) t3 ON t1.Date = t3.Date AND t1.Time = t3.Time AND CAST(t1.TotalAcc AS INTEGER) = t3.max_total_acc GROUP BY t1.Date ORDER BY t1.Date DESC;
注意事项
如果业务允许修改表结构,建议将Acc、TotalAcc、Proc、TotalProc这类数值字段改为INTEGER类型,避免每次查询都需要做类型转换,也能规避字符串排序带来的逻辑错误。
内容的提问来源于stack exchange,提问作者pipettejockey
相关产品推荐
相关产品推荐

