当前位置: 首页 > 面试题库 >

奇怪的MySQL AVG()异常NULL值

金兴朝
2023-03-14
问题内容

我在做什么 :

create table sample (id INT(10) PRIMARY KEY AUTO_INCREMENT,name varchar(255),marks INT(10));

insert into sample (name,marks) VALUES('sam',10);
insert into sample (name,marks) VALUES('sam',20);
insert into sample (name,marks) VALUES('sam',NULL);
insert into sample (name,marks) VALUES('sam',NULL);
insert into sample (name,marks) VALUES('sam',30);

select AVG(marks) from sample GROUP BY(name);

我预期的输出:

平均=(10 + 20 + 30)/ 5 = 12

MYSQL的输出:

平均值=(10 + 20 + 30)/ 3 = 20

理想情况下,我想要的是MYSQL应该得到5行的总和并除以5,但是它只能除以3(非NULL行)

为什么会发生这种情况,我该怎么做才能获得正确的AVG,即60/5?PS:我不能使标记字段NOT NULL,在我的数据库设计中,标记字段允许为NULL。

谢谢


问题答案:

这是正确的行为,因为NULL与number不同0

从概念上讲,它NULL意味着“缺失的未知值”,并且与其他值的处理方式有所不同。这就是为什么聚合函数(如AVG()ignore NULLs)的原因。

AVG()仅计算所有 已知值 的平均值。(= 不为 NULL =未知)

从MySQL文档:

除非另有说明,否则组函数将忽略NULL值。

另外,请 在MySQL手册的“
3.3.4.6使用NULL值”
中阅读有关NULLs 的概念。

为了得到想要的东西,你可以做

SELECT AVG(IFNULL(marks, 0)) 
FROM sample 
GROUP BY name;

IFNULL()如果值是NULL或通过该值,则返回第二个参数进行计算。

关于…的概念还有更多的误解NULL。在手册的“ 5.5.3
NULL问题”
中也对此进行了说明:

  • 在SQL中,与其他任何值(甚至是NULL)相比,“ NULL”值从不为真。除非文档中针对表达式所涉及的运算符和函数另有说明,否则包含NULL的表达式始终会产生NULL值。

    即:NULL == 0导致NULL而不是true。同样,NULL == NULL也会导致NULL而不是true。

  • 要搜索“ NULL”的列值,不能使用“ expr = NULL”测试。要查找“ NULL”值,必须使用“ IS NULL”测试。

  • 当使用“ DISTINCT”,“ GROUP BY”或“ ORDER BY”时,所有“ NULL”值均视为相等。

  • 当使用ORDER BY时,NULL值首先出现,或者如果您指定DESC以降序排序则最后出现。

  • 对于某些数据类型,MySQL特别处理NULL值。如果将“ NULL”插入“ TIMESTAMP”列,则会插入当前日期和时间。

  • 如果将“ NULL”插入具有“ AUTO_INCREMENT”属性的整数或浮点列中,则会插入序列中的下一个数字。

  • 定义了UNIQUE键的列仍然可以包含多个NULL值。



 类似资料:
  • 问题内容: 基本上,该网站可以正常运行12多个小时,然后突然停止工作。我将开始在以前运行良好的LINQ查询中引发奇怪的异常。 我在这篇文章的底部提供了堆栈跟踪。 根据在类似SO帖子上找到的建议,我通过直接从Server Explorer中的DB拖动表来删除并重新制作了DBML。比较Git中的新旧内容,我发现了一些不同的字段: 在dbml中将varchar(255)的一个实例设置为nchar(10)

  • 我有一个基于Spring的webapp,我的问题是在代码更改后,我开始出现延迟加载异常。下面我详细描述了这种情况: 在开始的时候 我有一个账户和文字实体。一个帐户可以有多个单词,一个单词可以分配给多个帐户。 一个ccount.class 单词班 除了每个账户只能有一个“WordForToday”,它由账户中映射的单词实体表示。类如下: 一切都正常工作。特别是我有一个@Schedilly方法,每天调

  • 问题内容: 鉴于此程序: Sun的(v 1.6.0_24)产生以下字节码: 带有以下异常表: 我的问题是: 为什么到底在异常表中包括了最后一个条目? 据我了解,它基本上说“ 如果引发异常,请捕获它,然后重试相同的指令 ”。 即使使用空try / catch / finally子句(例如 一些观察 Eclipse编译器不会产生任何此类异常表条目 JVM规范没有记录该指令的任何运行时异常。 我知道JV

  • 我将数据保存到会话中,但是我尝试将其读回,结果为空。Spring MVC是我的后端,Angular 4是前端。 爪哇: 角: 你知道我错过了什么吗?也许是CORS的事?

  • 问题内容: 有人可以解释一下为什么在第一种情况下检测到空指针,而在另一种情况下却没有吗? 也许他总是看第一种类型,但是为什么他只在条件为假的情况下才这样做。 问题答案: 当您使用三元运算符时, 转换时,类型1和类型2必须具有相同的类型。首先,它实现了type1,然后实现了type2。 现在看看你的情况 因为is 并且它将作为原始,并且因为正试图将其转换为。因此为空指针。 在哪里一样棘手的测试5 由

  • 下面的代码返回一个错误,它不会连接到SQlite db。 虽然下面的代码工作得很好。 你能帮我了解一下这两个代码之间的区别吗?为什么第一个不能编译?