问题发现背景
在昨天的工作中,遇到了一个MySQL查询查询记录统计个数的需求,于是直接在MyBatis的XML里面写了SQL进行查询.
SQL语句如下:
SELECT COUNT(*)
FROM paytixianapply y
WHERE y.cashierid=1 AND y.state=3 GROUP BY y.cashierid
结果接口测试时候发现报错.大概是这样的错误:
null不可赋值给int
由于错误已经修改所以找不到报错信息了!
当时考虑是Mapper里面的resultType设置的是Integer,而Service里获取结果是用的int的关系,后来改成Integer还是不行.
解决问题过程
后来查阅了一些资料,发现应该是SQL的执行结果为空,所以返回值为null,Integer包装类也就为null,当然不能赋值给int了.
于是我考虑使用IFNULL函数,将SQL修改为:
SELECT IFNULL(COUNT(*),0)
FROM paytixianapply y
WHERE y.cashierid=1 AND y.state=3 GROUP BY y.cashierid
而且这次为了避免出错,预先在Navicat工具里尝试运行这条查询语句.
结果返回值依然为null
百思不得其解.以为是MySQL不支持IFNULL函数的原因.但是由于昨天接口继续提交,所以将null在Java中进行了处理,如果返回值为null,则给值赋值为0.
问题原因
但是在今天的工作中,在以前的代码里发现了一句也是用IFNULL函数的语句.区别是我昨天IFNULL里面是COUNT函数,今天看到的是SUM函数.
语句如下:
SELECT ifnull(SUM(questionprice),0.00) as sumindeed FROM payincomeuser WHERE questionuserid=10001019
正好今天工作内容不多,于是专心下来研究这个问题.在继续翻阅一些关于COUNT函数的资料之后.发现原因是:
在WHERE语句之后筛选条件的结果为空,或使用了GROUP BY.导致COUNT函数的返回值为NULL;
然而当COUNT为NULL时,不能直接像SUM函数那样IFNULL,而是要将整个查询作为IFNULL函数的第一个参数.
解决办法
最后将SQL语句改为如下写法:
将整个查询作为函数的第一个参数就可以了
SELECT ifnull(
(select COUNT(*) as cncount
FROM paytixianapply y
WHERE y.cashierid=1 AND y.state=3 GROUP BY y.cashierid),0) as account
结果就对了
太坑了啊啊啊啊!