SQL聚合函数SUM值为NULL引发的爆炸

简介: 在写这篇文章之前,最想提醒大家的是,开发一定不能想当然,看着没问题就不调试了,结果它就是有问题的。如果时间很紧,到了测试阶段才发现问题解决问题那就很狼狈很被动了,不要问我为什么会特别想提这个。

在写这篇文章之前,最想提醒大家的是,开发一定不能想当然,看着没问题就不调试了,结果它就是有问题的。如果时间很紧,到了测试阶段才发现问题解决问题那就很狼狈很被动了,不要问我为什么会特别想提这个。

SQL 聚合函数SUM值为NULL引发的”爆炸“。

背景

场景是这样的,一个简单的功能实现,直接以SQL语句依靠MYSQL DB直接来实现并发锁(关于锁不理解可以看这里)。语句是这样的:

update tbGift2 a, (select sum(iValue) as cnt from tbGift2 where iHostUin = '327693651' and iStatus = 1) b, (select count(*) as cnt from tbGift2 where iReceiveUin = '318713931') c set a.iStatus=1,a.iValue=2,a.iReceiveUin=3187139331, a.dtReceiveAt = now() where a.id =3 and iStatus = 0 and 8>= b.cnt+2 and 2>c.cn;

这句语句的大概意思是,要更新表数据,并且聚合sum值+2要小于等于8,count值要小于2条。咋一看,这语句没毛病吧。看起来确实也没什么问题,where条件限制了并发的发生。但是,奇怪的事情发生了,这个语句执行是不成功的!!然后代码功能就自爆了。

现场勘察

小马排查了语法,然后单独去掉8>= b.cnt+2的条件,既然执行成功了。所以这个条件很可能是false。查一下select sum(iValue) as cnt from tbGift2 where iHostUin = '327693651' and iStatus = 1语句的结果,既然是NULL。是的,你没有看错,当没有聚合记录的时候这个值就是NULL而不是0,尽管我的iValue字段是int型。NULL又如何0又如何?是的,SQL这里还有个坑,NULL是不能做比较的,只能用ISNULL,IFNULL等,用NULL作为比较的话,尽管是NULL==NULL,结果也是false。这可不是PHP哦,比较能自动转换类型。就算NULL+1=也是等于Null

解决

解决方案参考:

1、使用isnull()方法进行判断,如isnull(sum(cnt),0),其中0为默认值,如果sum(cnt)的结果为null,则赋值 0;同理此方法可用于某字段,isnull(cnt,0),这样就可以排除一些值为null的数值型字段了。而如果这样 isnull(sum(isnull(cnt,0)),0),这样就可保万无一失了。

2、使用case when else流程控制语句,如可以用"case when sum(cnt) is null then 0 else sum(cnt) end"来代替sum(cnt),其中0同上一条的意义相同。

解决后的语句:

update tbGift2 a, (select COALESCE(SUM(iValue),0) as cnt from tbGift2 where iHostUin = '327693651' and iStatus = 1) b, (select count(*) as cnt from tbGift2 where iReceiveUin = '318713931') c set a.iStatus=1,a.iValue=2,a.iReceiveUin=3187139331, a.dtReceiveAt = now() where a.id =3 and iStatus = 0 and 8>= b.cnt+2 and 2>c.cn;

执行正常。总算可以倒杯咖啡喝喝了。

image.png

别说这是我的BUG

相关文章
|
SQL 人工智能 数据挖掘
如何在`score`表中正确使用`COUNT`和`AVG`函数?SQL聚合函数COUNT与AVG使用指南
本文三桥君通过score表实例解析SQL聚合函数COUNT和AVG的常见用法。详解COUNT(studentNo)、COUNT(score)、COUNT()的区别,以及AVG函数对数值/字符型字段的不同处理,特别指出AVG()是无效语法。实战部分提供6个典型查询案例及结果,包含创建表、插入数据的完整SQL代码。产品专家三桥君强调正确理解函数特性(如空值处理、字段类型限制)对数据分析的重要性,帮助开发者避免常见误区,提升查询效率。
616 0
|
SQL 存储 数据库
SQL NOT NULL
【11月更文挑战第14天】
677 6
|
SQL 存储 数据库
SQL学习一:ACID四个特性,CURD基本操作,常用关键字,常用聚合函数,五个约束,综合题
这篇文章是关于SQL基础知识的全面介绍,包括ACID特性、CURD操作、常用关键字、聚合函数、约束以及索引的创建和使用,并通过综合题目来巩固学习。
738 1
|
Java 数据库连接 数据库
mybatis plus 更新值为null的字段
mybatis plus 更新值为null的字段
871 7
|
SQL
SQL NOT NULL 约束
【7月更文挑战第18天】SQL NOT NULL 约束。
266 6
|
SQL
SQL NOT NULL 约束
【7月更文挑战第16天】SQL NOT NULL 约束。
193 3
|
SQL 数据挖掘 关系型数据库
SQL中的聚合函数:数据分析的强大工具
【8月更文挑战第31天】
1116 0
|
SQL 数据挖掘 BI
【超实用技巧】解锁SQL聚合函数的奥秘:从基础COUNT到高级多表分析,带你轻松玩转数据统计与挖掘的全过程!
【8月更文挑战第31天】SQL聚合函数是进行数据统计分析的强大工具,可轻松计算平均值、求和及查找极值等。本文通过具体示例,展示如何利用这些函数对`sales`表进行统计分析,包括使用`COUNT()`、`SUM()`、`AVG()`、`MIN()`、`MAX()`等函数,并结合`GROUP BY`和`HAVING`子句实现更复杂的数据挖掘需求。通过这些实践,你将学会如何高效地应用SQL聚合函数解决实际问题。
489 0
|
SQL 存储 索引
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
MySQL设计规约问题之为什么应该把字段定义为NOT NULL并且提供默认值
|
SQL MySQL 关系型数据库
SQL NULL 值【摘自W3C】
SQL NULL 值 本章讲解 IS NULL 和 IS NOT NULL 操作符。 NULL 值是遗漏的未知数据。默认地,表的列可以存放 NULL 值。 如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。
1149 0

热门文章

最新文章