本文揭示了使用多个 max()/min() 时返回错误结果的根本原因:温度字段被定义为字符串类型,导致按字典序而非数值大小比较;解决方案是将列改为 decimal 或 float 等数值类型。
在 MySQL 中,完全允许在同一查询中使用多个 MAX() 和 MIN() 聚合函数——语法合法、性能高效,也无数量限制。你遇到的“MAX(t1) 返回 9.63、MIN(t1) 返回 10.00”这类明显违背数学逻辑的结果,并非 SQL 写法错误,而是数据类型设计缺陷所致。
当温度字段(如 t1)被定义为 VARCHAR、TEXT 或其他字符串类型时,MySQL 会按字典序(lexicographic order) 进行比较,而非数值大小。例如:
SELECT MAX('9.63'), MIN('10.0'), MAX('9.63', '10.0');
-- 实际结果:'9.63', '10.0', '9.63'(因为 '9' > '1')这是因为字符串比较从左到右逐字符进行:
这正是你观察到“9.63 被当作最大值”“10.0 被当作最小值”的技术根源。
请立即将相关温度字段修改为合适的数值类型。推荐如下:
| 场景 | 推荐类型 | 示例定义 | 说明 |
|---|---|---|---|
| 高精度温控(如工业传感器) | DECIMAL(5,2) | t1 DECIMAL(5,2) | 精确存储 ±999.99,无浮点误差,适合统计与报表 |
| 通用物联网采集(允许微小误差) | FLOAT | t1 FLOAT | 存储范围大,性能略优,但需注意二进制浮点精度问题 |
执行修改语句(
以 t1 为例):
ALTER TABLE Buapas MODIFY COLUMN t1 DECIMAL(5,2); -- 若表名由 $idpass 动态指定,请替换为实际表名
⚠️ 注意:修改前请务必备份数据,并确认无应用层代码依赖字符串解析逻辑(如正则提取小数位)。
修改类型后,原查询即可准确返回数值极值:
SELECT MIN(t1) AS t1min, MAX(t1) AS t1max, MIN(t2) AS t2min, MAX(t2) AS t2max FROM Buapas WHERE logdate >= NOW() - INTERVAL 1 DAY;
此时 MAX(t1) 将真正返回过去 24 小时内的最高温度(如 10.38),MIN(t1) 返回最低值(如 9.06),符合物理意义与业务预期。
总结:聚合函数本身没有问题,问题永远出在数据建模的第一公里。用对类型,MAX() 和 MIN() 就是最可靠、最高效的极值计算工具。