SQL中的三值逻辑和NULL

embedded/2025/2/6 6:50:48/

        在SQL中,三值逻辑是一个重要概念,它的存在主要是由于 NULL 值的引入。NULL 代表未知值,它既不是空字符串,也不是数字 0,而是一个特殊的标记,表示数据缺失或不可用。

目录

SQL的三值逻辑

NULL的特性

NULL在SQL逻辑运算中的影响

1. 逻辑运算 (AND, OR, NOT)

2. NULL参与比较 (=, !=, >, <, etc.)

3. NULL在IN 和 NOT IN中的影响

4. NULL在DISTINCT、GROUP BY 和 ORDER BY 中

5. NULL在 COALESCE 和 IFNULL 处理

NULL 在 JOIN 中的影响

如何正确处理 NULL

总结(重点)


SQL的三值逻辑

在SQL中,由于NULL值的存在,导致它使用了一种特殊的逻辑作用法:三值逻辑 (Three-Valued Logic, 3VL)

其包括三个任何逻辑计算的可能结果:

  • TRUE (真)

  • FALSE (假)

  • UNKNOWN (未知)

NULL在SQL中表示“未知”或“缺失的值”,它与普通的值有很大区别。由于NULL表示未知值,所以任何与NULL进行运算的结果都应该是UNKNOWN,而不是TRUE或FALSE。


NULL的特性

NULL并不是一个具体值,而是一个特殊状态,其具有如下特性:

  1. NULL不能相互比较:NULL = NULL结果不是TRUE,而是UNKNOWN。

  2. NULL参与数值运算,结果为NULLNULL + 10的结果仍然是NULL

  3. NULL参与逻辑运算,会影响逻辑结果:

    • TRUE AND NULL,结果是UNKNOWN

    • FALSE OR NULL,结果是UNKNOWN

如果WHERE条件结果为UNKNOWN,那么该记录将不会被查询结果包含。


NULL在SQL逻辑运算中的影响

1. 逻辑运算 (AND, OR, NOT)

AND运算

表达式结果
TRUE AND TRUETRUE
TRUE AND FALSEFALSE
TRUE AND UNKNOWNUNKNOWN
FALSE AND UNKNOWNFALSE
UNKNOWN AND UNKNOWNUNKNOWN

 OR运算

表达式结果
TRUE OR UNKNOWNTRUE
FALSE OR UNKNOWNUNKNOWN
UNKNOWN OR UNKNOWNUNKNOWN

NOT运算 

表达式结果
NOT TRUEFALSE
NOT FALSETRUE
NOT UNKNOWNUNKNOWN

2. NULL参与比较 (=, !=, >, <, etc.)

表达式结果
NULL = NULLUNKNOWN
NULL != NULLUNKNOWN
NULL > 10UNKNOWN
NULL < 10UNKNOWN
NULL IS NULLTRUE
NULL IS NOT NULLFALSE

3. NULLINNOT IN中的影响

如果 NULL 出现在 INNOT IN 语句中,会导致不可预期的结果:

SELECT * FROM users WHERE age IN (20, 30, NULL);

由于 NULL 是未知值,SQL 不知道 NULL 是否属于 age,导致 UNKNOWN,最终查询只会匹配 age=20age=30,但不会匹配 NULL

更严重的问题出现在 NOT IN 中:

SELECT * FROM users WHERE age NOT IN (20, 30, NULL);

由于 NULLIN 语句中会返回 UNKNOWN,整个 NOT IN 变成 UNKNOWN,最终不会返回任何数据。

解决方法:

SELECT * FROM users WHERE age NOT IN (20, 30) OR age IS NULL;

4. NULL在DISTINCT、GROUP BY 和 ORDER BY 中

  • DISTINCTNULL 为相同值:

    SELECT DISTINCT category FROM products;

    如果 category 列中有多个 NULLDISTINCT 只会保留一个 NULL

  • GROUP BYNULL 为一个分组:

    SELECT category, COUNT(*) FROM products GROUP BY category;

    所有 NULL 值会被归为同一组。

  • ORDER BY 处理 NULL

    SELECT * FROM employees ORDER BY salary ASC;

    NULL 默认排在最前或最后,具体行为取决于数据库:

    • PostgreSQL: NULLS FIRSTNULLS LAST

    • MySQL: NULL 默认排在最前

    • SQL Server: NULL 默认排在最前

5. NULL在 COALESCE 和 IFNULL 处理

要避免 NULL 影响查询,可以使用 COALESCEIFNULL 进行处理:

  • COALESCE(expr1, expr2, ..., exprN):返回第一个非NULL值

    SELECT name, COALESCE(email, '未知') AS email FROM users;
  • IFNULL(expr, default_value)(MySQL 专用)

    SELECT name, IFNULL(email, '未知') AS email FROM users;

NULL 在 JOIN 中的影响

如果 NULL 存在于 JOIN 的关联列中,则该行不会被匹配:

SELECT * FROM orders
LEFT JOIN customers ON orders.customer_id = customers.id;

如果 orders.customer_idNULL= NULL 结果是 UNKNOWN,导致 INNER JOIN 失败。

LEFT JOIN 可以保留 orderscustomers 数据为 NULL

如何正确处理 NULL

  1. 查询时使用 IS NULLIS NOT NULL

    SELECT * FROM users WHERE email IS NULL;
  2. 避免 NULL 影响逻辑运算

    SELECT * FROM orders WHERE discount IS NULL OR discount > 10;
  3. JOIN 中考虑 NULL 可能带来的问题

    SELECT * FROM orders
    LEFT JOIN customers ON orders.customer_id = customers.id
    WHERE customers.id IS NOT NULL;
  4. 使用 COALESCE() 处理 NULL

    SELECT name, COALESCE(email, '未知') AS email FROM users;
  5. 正确使用 NOT IN

    SELECT * FROM users WHERE age NOT IN (20, 30) OR age IS NULL;

总结(重点)

  • NULL 代表未知,不是空字符串或 0。
  • SQL 采用三值逻辑(TRUE, FALSE, UNKNOWN),导致 NULL 参与运算时可能返回 UNKNOWN
  • NULL 不能用 = 直接比较,而要使用 IS NULLIS NOT NULL
  • NULL 可能影响 JOINGROUP BYORDER BYIN/NOT IN 等查询,必须小心处理。
  • 使用 COALESCE()IFNULL() 等函数可以避免 NULL 带来的问题。

http://www.ppmy.cn/embedded/159956.html

相关文章

【单层神经网络】softmax回归的从零开始实现(图像分类)

softmax回归 该回归分析为后续的多层感知机做铺垫 基本概念 softmax回归用于离散模型预测&#xff08;分类问题&#xff0c;含标签&#xff09; softmax运算本质上是对网络的多个输出进行了归一化&#xff0c;使结果有一个统一的判断标准&#xff0c;不必纠结为什么要这么算…

Java NIO详解

一、NIO简介 NIO 中的 N 可以理解为 Non-blocking&#xff0c;不单纯是 New&#xff0c;是解决高并发、I/O高性能的有效方式。 Java NIO 是Java1.4之后推出来的一套IO接口&#xff0c;NIO提供了一种完全不同的操作方式&#xff0c; NIO支持面向缓冲区的、基于通道的IO操作。 …

unity学习26:用Input接口去监测: 鼠标,键盘,虚拟轴,虚拟按键

目录 1 用Input接口去监测&#xff1a;鼠标&#xff0c;键盘&#xff0c;虚拟轴&#xff0c;虚拟按键 2 鼠标 MouseButton 事件 2.1 鼠标的基本操作 2.2 测试代码 2.3 测试情况 3 键盘Key事件 3.1 键盘的枚举方式 3.2 测试代码同上 3.3 测试代码同上 3.4 测试结果 4…

第 1 天:UE5 C++ 开发环境搭建,全流程指南

&#x1f3af; 目标&#xff1a;搭建 Unreal Engine 5&#xff08;UE5&#xff09;C 开发环境&#xff0c;配置 Visual Studio 并成功运行 C 代码&#xff01; 1️⃣ Unreal Engine 5 安装 &#x1f539; 下载与安装 Unreal Engine 5 步骤&#xff1a; 注册并安装 Epic Game…

修复使用unplugin-auto-import和unplugin-vue-components后tsc-vue报错的问题

在使用NaiveUI的过程中&#xff0c;引入了unplugin-auto-import和unplugin-vue-components。 这两个组件能自动引入vue方法和vue组件&#xff0c;提升了开发者体验。 但是在vscode中&#xff0c;源码里未手动引用而直接用的方法和组件还是被标红&#xff0c;提示找不到&#x…

【llm对话系统】大模型 Llama 如何进行量化和推理

1. 写在前面 Llama 是 Meta AI 开源的一系列大型语言模型 (LLM),在各种 NLP 任务上表现出色。然而,这些模型通常具有庞大的参数量,需要大量的计算资源和内存才能进行推理。为了降低 Llama 模型的部署成本,并提高其推理速度,我们可以采用模型量化 (Quantization) 技术。 …

Mac M1 ComfyUI 中 AnyText插件安装问题汇总?

Q1&#xff1a;NameError: name ‘PreTrainedTokenizer’ is not defined ? 该项目最近更新日期为2024年12月&#xff0c;该时间段的transformers 版本由PyPI 上的 transformers 页面 可知为4.47.1. A1: transformers 版本不满足要求&#xff0c;必须降级transformors &#…

Linux系统 环境变量

环境变量 写在前面概念查看环境变量main函数的参数argc & argvenv bash环境变量 写在前面 对于环境变量&#xff0c;本篇主要介绍基本概念及三四个环境变量 —— PATH、HOME、PWD。其中 PATH 作为 “ 敲门砖 ”&#xff0c;我们会更详细讲解&#xff1b;理解环境变量的全局…