MySQL的sum函数返回的类型

本文探讨了MySQL中SUM函数返回值类型的差异,并给出了在不同数据库版本下如何处理这些类型差异的具体解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天项目切换数据库时,出错

访问数据库的代码大概是这样:

String sql = "select sum(number) as sumNumberOfOneDay from tableName";
List<Map> rows = getJdbcTemplate().queryForList(sql);
for (Map row : rows) {
SomeBean item = new SomeBean();
item.setSumNumberOfOneDay(objectToInt(row.get("sumNumberOfOneDay")));

}

private int objectToInt(Object obj) {
return Integer.parseInt("" + obj);
}


表字段“number”的类型是int(10) unsigned

连接数据库DataBaseA,测试运行正常;切换到另一数据库DataBaseB(数据库表,表名,表结构一样)时,发现报错:
java.lang.NumberFormatException: For input string: "10.0"

把sql语句拷贝到MySQL命令行窗口里面直接执行,sum(number)返回的值是10;
但在Spring的getJdbcTemplate().queryForList(sql)返回,则变成了10.0,
打印row.get("sumNumberOfOneDay").getClass()的结果是:class java.lang.Double

切回DataBaseA,打印结果是java.math.BigDecimal

两个数据库的查询结果在MySQL命令行窗口返回整数,但在Java程序中返回浮点数

那不用Spring,直接操作JDBC:
	Connection conn = getJdbcTemplate().getDataSource().getConnection();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
String name = rsmd.getColumnName(i);
String type = rsmd.getColumnTypeName(i);
System.out.println(name + ", " + type);
}

DataBaseA打印的结果:
sumNumberOfOneDay, DECIMAL

DataBaseB打印的结果:
sumNumberOfOneDay, DOUBLE

基本可判断是MySQL的问题

网上搜索一下,果然:

The SUM() and AVG() functions return a DECIMAL value for exact-value arguments (integer or DECIMAL), and a DOUBLE value for approximate-value arguments (FLOAT or DOUBLE). (Before MySQL 5.0.3, SUM() and AVG() return DOUBLE for all numeric arguments.)

[url]http://stackoverflow.com/questions/10592481/what-is-the-return-type-of-sum-in-mysql[/url]

原来MySQL 5.0.3之前的版本,sum函数返回的是DOUBLE类型

回头检查一下MySQL的版本:

DataBaseA:
5.1.44 Source distribution

DataBaseB:
4.1.7-standard-log

果然是这样

解决办法:
1.笨方法,就是重写objectToInt方法:
	if (obj instanceof Double) {
return ((Double)obj).intValue();
}
if (obj instanceof BigDecimal) {
return ((BigDecimal)obj).intValue();
}
return Integer.parseInt(obj.toString());

2.利用Spring的BeanPropertyRowMapper:
List<SomeBean> list = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(SomeBean.class));

应该尽量采用方法2,避免自己处理

查看一下Spring的getJdbcTemplate().query(sql, new BeanPropertyRowMapper(SomeBean.class))方法,
发现它的大体思路是这样:
1.通过SomeBean.class得到所有property
2.根据property的类型,调用ResultSet.getXXX()得到对应的值
在ResultSet.getXXX()方法里面,就实现了类型转换
例如com.mysql.jdbc.Result的getInt方法(关键部分的代码):
val = getString(columnIndex);
if ((val != null) && (val.length() != 0)) {
if ((val.indexOf("e") == -1) && (val.indexOf("E") == -1)
&& (val.indexOf(".") == -1)) {
return Integer.parseInt(val);
} else {
// Convert floating point
return (int) (Double.parseDouble(val));
}
} else {
return 0;
}

### 使用 `SUM` 函数进行求和操作 MySQL 中的 `SUM` 函数是一种常用的聚合函数,用于计算指定列的总和。该函数通常在 `SELECT` 语句中使用,并且可以结合别名对结果命名。`SUM` 函数仅适用于数值型数据,例如整数或浮点数类型的列,对于非数值类型(如字符串、日期等)无法直接应用。 以下是一个简单的示例,展示如何使用 `SUM` 函数: ```sql SELECT SUM(sales_amount) AS total_sales FROM sales; ``` 上述查询将返回 `sales_amount` 列的总和,并将其命名为 `total_sales`。如果该列包含 `NULL` 值,则 `SUM` 函数会自动忽略这些值,只对非 `NULL` 值进行求和。若需要将 `NULL` 值视为特定数值参与计算,可以通过 `IFNULL` 或 `COALESCE` 函数进行转换处理[^3]。 ### 结合条件过滤数据 `SUM` 函数可以与 `WHERE` 子句配合使用,以筛选满足特定条件的数据并对其进行求和。例如,假设有一张订单表 `orders`,其中包含字段 `order_date` 和 `amount`,要计算某个时间段内的订单总额,可以编写如下查询: ```sql SELECT SUM(amount) AS total_orders FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31'; ``` 此查询将计算 2023 年全年所有订单金额的总和[^3]。 ### 分组统计 当需要根据不同类别或分组进行求和时,可以将 `SUM` 函数与 `GROUP BY` 子句结合使用。例如,假设有一个产品销售表 `product_sales`,其中包含字段 `category` 和 `sale_price`,要按商品类别统计销售额总和,可以执行以下查询: ```sql SELECT category, SUM(sale_price) AS total_sales_by_category FROM product_sales GROUP BY category; ``` 该查询将按照 `category` 字段分组,并分别计算每个类别的销售总额[^2]。 ### 控制小数位数 有时,`SUM` 函数返回的结果可能带有较多的小数位,这可能会影响可读性。为了控制小数位数,可以使用 `ROUND`、`TRUNCATE` 或 `FORMAT` 等函数。例如,若希望将结果保留两位小数,可以使用以下方法之一: ```sql -- 使用 ROUND 函数四舍五入到两位小数 SELECT ROUND(SUM(sale_price), 2) AS rounded_total FROM product_sales; -- 使用 TRUNCATE 函数截断多余小数 SELECT TRUNCATE(SUM(sale_price), 2) AS truncated_total FROM product_sales; -- 使用 FORMAT 函数格式化输出(注意:FORMAT 返回字符串) SELECT FORMAT(SUM(sale_price), 2) AS formatted_total FROM product_sales; ``` 这些函数可以帮助更好地控制最终输出的小数精度,从而提升用户体验和数据呈现效果[^1]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值