Strange MySQL AVG() anomaly NULL values(奇怪的 MySQL AVG() 异常 NULL 值)
问题描述
我在做什么:
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
AVG = (10+20+30)/5 = 12
MYSQL的输出:
平均值 = (10+20+30)/3 = 20
AVG = (10+20+30)/3 = 20
理想情况下,我想要的是 MYSQL 应该得到 5 行的总和并将其除以 5,但它只除以 3(非 NULL 行)
Ideally what i wanted is that MYSQL should get the sum of 5 rows and divide it by 5 , but it only divides by 3 (the non-NULL rows)
为什么会发生这种情况,我该怎么做才能获得正确的 AVG,即 60/5?PS:我不能让标记字段为 NOT NULL ,在我的数据库设计中,标记字段允许为 NULL.
Why does this occur and what can i do to get the correct AVG ie 60/5 ? PS: I cannot make the marks field NOT NULL , in my db design the marks field is allowed to be NULL.
谢谢
推荐答案
这是正确的行为,因为 NULL 与数字 0 不同.
这可能会让一些不会说英语的人感到惊讶,因为在许多语言中,null"是指null".等价于零".
This is the correct behavior, because NULL is not the same as the number 0.
This might surprise some non-english speakers, because in many languages "null" is equivalent to "zero".
概念上,NULL 指的是未知值",因此它与其他值的处理方式不同.这就是为什么聚合函数像AVG() 忽略 NULLs.
AVG() 计算所有已知"的平均值.仅值.(= 不是 NULL)
来自 MySQL 文档:
除非另有说明,否则组函数会忽略 NULL 值.
Unless otherwise stated, group functions ignore NULL values.
此外,请阅读 NULL 概念" rel="nofollow noreferrer">MySQL 手册的3.3.4.6 使用 NULL 值"部分.
Also, read about the concept of NULLs in Section "3.3.4.6 Working with NULL Values" of the MySQL manual.
为了得到你想要的,你可以这样做
To get what you want, you might do
SELECT AVG(IFNULL(marks, 0))
FROM sample
GROUP BY name;
IFNULL()<如果值为 NULL,则/code> 返回计算的第二个参数,否则通过该值.
IFNULL() returns the second argument for calculations if the value is NULL or passes through the value otherwise.
对于NULL 的概念有更多常见的误解.这些也在部分5.5.3 问题"中进行了解释使用手册的 NULL":
There are more common misunderstandings regarding the concept of NULL. These are also explained in Section "5.5.3 Problems with NULL" of the manual:
- 在 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值.
- In SQL, the
NULLvalue is never true in comparison to any other value, evenNULL. An expression that containsNULLalways produces aNULLvalue unless otherwise indicated in the documentation for the operators and functions involved in the expression.
i.e.:NULL == 0results in NULL instead oftrue. AlsoNULL == NULLresults in NULL, instead of true.- To search for column values that are
NULL, you cannot use anexpr = NULLtest. To look forNULLvalues, you must use theIS NULLtest.- When using
DISTINCT,GROUP BY, orORDER BY, allNULLvalues are regarded as equal.- When using
ORDER BY,NULLvalues are presented first, or last if you specifyDESCto sort in descending order.- For some data types, MySQL handles NULL values specially. If you insert
NULLinto aTIMESTAMPcolumn, the current date and time is inserted.- If you insert
NULLinto an integer or floating-point column that has theAUTO_INCREMENTattribute, the next number in the sequence is inserted.- A column that has a
UNIQUEkey defined can still contain multipleNULLvalues.
这篇关于奇怪的 MySQL AVG() 异常 NULL 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:奇怪的 MySQL AVG() 异常 NULL 值
- 如何将 Byte[] 插入 SQL Server VARBINARY 列 2021-01-01
- 在SQL中,如何为每个组选择前2行 2021-01-01
- 以一个值为轴心,但将一行上的数据按另一行分组? 2022-01-01
- 如何使用 pip 安装 Python MySQLdb 模块? 2021-01-01
- 使用 Oracle PL/SQL developer 生成测试数据 2021-01-01
- 远程 mySQL 连接抛出“无法使用旧的不安全身份验证连接到 MySQL 4.1+"来自 XAMPP 的错误 2022-01-01
- 更改自动增量起始编号? 2021-01-01
- SQL 临时表问题 2022-01-01
- 如何将 SonarQube 6.7 从 MySQL 迁移到 postgresql 2022-01-01
- 导入具有可变标题的 Excel 文件 2021-01-01
