SQLite中GROUP BY分组时SUM与TOTAL计算异常问题排查
问题
我写了下面的SQL查询,想按DateAndTime分组,统计每个时间点Load的count、min、max和sum值:
SELECT DateAndTime, count(Load), min(Load), max(Load), sum(Load) FROM UpdatedRegions GROUP BY DateAndTime ORDER BY DateAndTime;
示例数据如下:
DateAndTime Load 2028-01-01 00:00:00 9,382.3938 2028-01-01 00:00:00 4,662.4381 2028-01-01 00:00:00 2,328.2232 2028-01-01 00:00:00 815.0305 2028-01-01 00:00:00 6,118.7683 2028-01-01 00:00:00 1,791.7472 2028-01-01 00:00:00 228.7977 2028-01-01 01:00:00 8,865.7735 2028-01-01 01:00:00 4,436.1125 2028-01-01 01:00:00 2,236.8587 2028-01-01 01:00:00 789.5337 2028-01-01 01:00:00 5,787.2574 2028-01-01 01:00:00 1,712.3446
现在遇到的问题是:count、min、max结果都对,但sum和total计算结果异常,比如2028-01-01 00:00:00的sum值是1065.8282,用total也得到同样错误结果。分组逻辑没问题,已经在SQLite 3.13.0和3.41.2两个版本测试过,都有这个问题。
解决方法
问题出在Load字段的类型和格式上:
- 你的
Load字段是字符串类型,而且数值里带了千位分隔符逗号(,)。 - SQLite对字符串做数值计算时,会从左到右解析,遇到非数字字符就停止。比如
9,382.3938会被解析成9,4,662.4381解析成4,把这些解析后的数值加起来正好是9+4+2+815+6+1+228=1065,和你得到的错误结果一致。 - 而min、max能正常工作是因为它们按字符串排序比较刚好符合预期,但这只是巧合,并非正确的数值比较逻辑。
有两种解决思路:
1. 修正字段类型(推荐)
直接把Load字段的类型改成REAL或NUMERIC,导入数据时去掉千位分隔符,确保存储的是纯数值。这样后续的sum、total计算就会正常,min和max也会基于真实数值比较。
2. 查询时临时处理
如果暂时不能修改字段,可以在查询时先去掉逗号,再转换成数值类型:
SELECT DateAndTime, count(Load), min(CAST(REPLACE(Load, ',', '') AS REAL)), max(CAST(REPLACE(Load, ',', '') AS REAL)), sum(CAST(REPLACE(Load, ',', '') AS REAL)) FROM UpdatedRegions GROUP BY DateAndTime ORDER BY DateAndTime;
这样就能正确计算sum,同时修正min、max的比较逻辑,避免字符串排序带来的潜在问题。
内容的提问来源于stack exchange,提问作者sammy
相关产品推荐
相关产品推荐

