首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第1章 数据库和SQL
1-1 数据库是什么
我们身边的数据库
为什么DBMS那么重要
DBMS的种类
1-2 数据库的结构
RDBMS的常见系统结构
表的结构
1-3 SQL概要
标准SQL
SQL语句及其种类
SQL的基本书写规则
1-4 表的创建
表的内容的创建
数据库的创建(CREATE DATABASE语句)
表的创建(CREATE TABLE语句)
命名规则
数据类型的指定
约束的设置
1-5 表的删除和更新
表的删除(DROP TABLE语句)
表定义的更新(ALTER TABLE语句)
向Product表中插入数据
第2章 查询基础
2-1 SELECT语句基础
列的查询
查询出表中所有的列
为列设定别名
常数的查询
从结果中删除重复行
根据WHERE语句来选择记录
注释的书写方法
算术运算符
需要注意NULL
比较运算符
对字符串使用不等号时的注意事项
不能对NULL使用比较运算符
2-3 逻辑运算符
NOT运算符
AND运算符和OR运算符
通过括号强化处理
逻辑运算符和真值
含有NULL时的真值
第3章 聚合与排序
3-1 对表进行聚合查询
聚合函数
计算表中数据的行数
计算NULL之外的数据的行数
计算合计值
计算平均值
计算值和小值
使用聚合函数删除重复值(关键字DISTINCT)
3-2 对表进行分组
GROUP BY子句
聚合键中包含NULL的情况
使用WHERE子句时GROUP BY的执行结果
与聚合函数和GROUP BY子句有关的常见错误
3-3 为聚合结果指定条件
HAVING子句
HAVING子句的构成要素
相对于HAVING子句,更适合写在WHERE子句中的条件
3-4 对查询结果进行排序
ORDER BY子句
指定升序或降序
指定多个排序键
NULL的顺序
在排序键中使用显示用的别名
ORDER BY子句中可以使用的列
不要使用列编号
当前位置:
首页>>
技术小册>>
SQL基础教程(上)
小册名称:SQL基础教程(上)
### 聚合键中包含NULL的情况 在SQL(Structured Query Language)中,聚合函数是处理数据集合的强大工具,它们能够对一组行执行计算并返回单个值。常见的聚合函数包括`SUM()`、`AVG()`、`COUNT()`、`MAX()`、`MIN()`等。然而,当我们在使用这些聚合函数时,尤其是当聚合键(即GROUP BY子句中的列)中包含NULL值时,SQL的行为可能会与预期有所不同,这取决于具体的数据库系统(如MySQL、PostgreSQL、SQL Server等),因为不同的数据库系统对NULL值的处理策略可能存在差异。本章将深入探讨聚合键中包含NULL值的情况,解析其背后的逻辑,并提供实际案例和解决方案。 #### 一、理解NULL值在SQL中的特殊性 在SQL中,NULL是一个特殊的标记,用于表示缺失的或未知的数据。NULL与任何值(包括它自己)的比较操作都会返回NULL,而不是TRUE或FALSE。这意味着,在进行聚合操作时,数据库需要有一套规则来处理包含NULL值的行。 #### 二、不同数据库系统对NULL的处理差异 ##### 1. MySQL 在MySQL中,当使用GROUP BY子句进行分组时,包含NULL值的行会被视为一个单独的分组。这意味着,如果你在GROUP BY子句中包含了可能为NULL的列,那么结果集中将包含一个以NULL为标识的分组,该分组包含了所有该列为NULL的行。 **示例**: 假设有一个名为`employees`的表,其中包含`department_id`(部门ID)和`salary`(薪水)两个字段,部分员工的`department_id`可能为NULL。 ```sql SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id; ``` 这个查询将返回每个部门ID的平均薪水,包括一个`department_id`为NULL的分组,代表那些未指定部门ID的员工的平均薪水。 ##### 2. PostgreSQL PostgreSQL同样将NULL值视为一个独立的分组,与MySQL的处理方式相似。这意味着,在GROUP BY子句中,包含NULL的行将被单独聚合并显示。 ##### 3. SQL Server SQL Server也遵循相同的逻辑,将NULL视为一个独特的分组值。因此,在GROUP BY操作中,包含NULL的行将自动形成一个单独的分组。 #### 三、处理聚合键中NULL值的策略 尽管大多数数据库系统都将NULL视为分组操作中的一个独特值,但在某些情况下,你可能希望将这些NULL值视为同一组或忽略它们。以下是几种处理策略: ##### 1. 使用COALESCE或IFNULL函数 `COALESCE`(在大多数SQL数据库系统中可用)和`IFNULL`(主要在MySQL中)函数可以用来将NULL值替换为另一个值,从而避免将NULL视为独立分组。 **示例**: ```sql SELECT COALESCE(department_id, 'Unknown') AS department_group, AVG(salary) AS avg_salary FROM employees GROUP BY COALESCE(department_id, 'Unknown'); ``` 这个查询将所有`department_id`为NULL的行视为一个名为'Unknown'的组,并计算该组的平均薪水。 ##### 2. 忽略NULL值 如果你想要完全忽略包含NULL值的行,可以使用WHERE子句来过滤掉这些行。 **示例**: ```sql SELECT department_id, AVG(salary) AS avg_salary FROM employees WHERE department_id IS NOT NULL GROUP BY department_id; ``` 这个查询仅计算了那些`department_id`非NULL的员工的平均薪水。 ##### 3. 使用CASE语句进行更复杂的逻辑处理 对于更复杂的场景,你可以使用`CASE`语句在GROUP BY之前对列值进行转换或分类。 **示例**: ```sql SELECT CASE WHEN department_id IS NULL THEN 'No Department' ELSE department_id END AS department_group, AVG(salary) AS avg_salary FROM employees GROUP BY CASE WHEN department_id IS NULL THEN 'No Department' ELSE department_id END; ``` 这个查询将所有未指定部门ID的员工归入了一个名为'No Department'的组。 #### 四、性能考虑 在处理包含大量NULL值的列时,使用`COALESCE`、`IFNULL`或`CASE`语句可能会对查询性能产生一定影响,尤其是当这些操作与大数据集一起使用时。因此,在设计数据库和查询时,应考虑到这些潜在的性能问题,并尽量在数据输入阶段就避免产生大量的NULL值,或者通过索引、表分区等策略来优化查询性能。 #### 五、结论 聚合键中包含NULL值的情况在SQL中是一个常见的问题,不同的数据库系统虽然对NULL的处理策略相似,但在实际应用中仍需要根据具体情况选择合适的处理方法。通过合理使用`COALESCE`、`IFNULL`、`CASE`语句以及WHERE子句,我们可以灵活地处理包含NULL值的聚合查询,以满足不同的业务需求。同时,我们也应关注这些操作对查询性能的影响,确保数据库的性能和效率。
上一篇:
GROUP BY子句
下一篇:
使用WHERE子句时GROUP BY的执行结果
该分类下的相关小册推荐:
PostgreSQL入门教程
SQL基础教程(下)
SQL基础教程(中)
高性能的Postgres SQL