评论

收藏

[MySQL] 那些年我们踩过的坑,SQL 中的空值陷阱!

数据库 数据库 发布于:2021-11-15 16:21 | 阅读数:408 | 评论:0

SQL 是一种声明式的语言,我们只需要描述想要的结果(WHAT),而不关心数据库如何实现(HOW);虽然 SQL 比较容易学习,但是仍然有一些容易混淆和出错的概念。
今天我们就来说说 SQL 中的空值陷阱和避坑方法,涉及的数据库包括 MySQL、Oracle、SQL Server、PostgreSQL 以及 SQLite。还是老规矩,结论先行:
NULL 特性MySQLOracleSQL ServerPostgreSQLSQLite三值逻辑✔️✔️✔️✔️✔️空值比较IS [NOT] NULL、expr <=> NULLIS [NOT] NULL'' IS NULLIS [NOT] NULLIS [NOT] NULLIS [NOT] DISTINCT FROM NULLIS [NOT] NULLNOT IN (NULL)不返回结果不返回结果不返回结果不返回结果不返回结果函数/表达式 NULL 参数结果为 NULL结果为 NULL、CONCAT 函数和 || 例外结果为 NULL、CONCAT 函数例外结果为 NULL、CONCAT 函数例外结果为 NULL聚合函数忽略 NULL 数据、COUNT() 除外忽略 NULL 数据、COUNT() 除外忽略 NULL 数据、COUNT(*) 除外忽略 NULL 数据、COUNT() 除外忽略 NULL 数据、COUNT() 除外DISTINCTGROUP BYPARTITION BYUNION所有空值分为一组所有空值分为一组所有空值分为一组所有空值分为一组所有空值分为一组ORDER BY默认空值最小默认空值最大、支持 NULLS FIRST | LAST默认空值最小默认空值最大、支持 NULLS FIRST | LAST默认空值最小、支持 NULLS FIRST | LASTCOALESCE 函数NULLIF 函数✔️、IFNULL(expr1, expr2)、IF(expr1, expr2, expr3)✔️、NVL(expr1, expr2)、NVL2(expr1, expr2, expr3)✔️、ISNULL(expr1, expr2)✔️✔️唯一约束允许多个空值✔️✔️❌✔️✔️检查约束允许插入空值✔️✔️✔️✔️✔️本文使用的示例数据可以点击链接《SQL 入门教程》示例数据库下载。
NULL 即是空
在数据库中,空值(NULL)是一个特殊的值,通常用于表示缺失值或者不适用的值。比如,填写问卷时不愿意透露某些信息会导致录入项的缺失,在公司的组织结构中总会有一个人(董事长/总经理)没有上级领导。
首先一点,空值与数字 0 并不相同。假如我问你:你的钱包里有多少钱?如果你知道里面没有钱,可以说是零;如果你不确定,那么就是未知,但不能说没有。当我们需要创建一个表来存储这个信息的时候,应该是 NULL;除非我们能够确定钱包里面没有钱或者有多少钱。
另外,空值与空字符串('')也不相同,原因和上面类似。但是 Oracle 是一个例外,我们会在下文具体讨论。
在大多数编程语言中,访问 null 值通常会导致错误;但是 SQL 不会出错,只是会影响到运算的结果而已。
三值逻辑
在大多数编程语言中,逻辑运算的结果只有两种情况,不是真(True)就是假(False)。但是对于 SQL 而言,逻辑运算还可能是未知(Unknown):
DSC0000.png
引入三值逻辑主要是为了支持 NULL,因为 NULL 代表的是未知数据。因此,SQL 中的逻辑运算与(AND)、或(OR)以及非(NOT)的结果如下:

AND真假未知真假未知假假假未知未知假未知OR真假未知真真真真假未知未知真未知未知NOT结果未知未知对于 AND 运算符而言,真和未知的与运算有可能是真,也有可能是假;因此,最终的结果是未知。
关注下面的标签,发现更多相似文章