故障013:易忘的NULL表达式

故障013:易忘的NULL表达式

    • 一、问题引入
    • 二、探索之路
      • 2.1 数据准备
      • 2.2 回顾NULL表达式
      • 2.3 重现问题
        • 2.3.1 分析原因
        • 2.3.2 如何化解预期?
    • 三、知识总结

一、问题引入

某单位开发人员理直气壮抛出一张截图,以红色醒目地标记问题,好似挑刺。咦!!!数据库不对头哟,等于或不等于查出结果一样,由此断定数据库可能有问题,过于决绝。这种陷阱极易掉进,因为等于和不等于不应该都相同的结果。如果没人深扒其原因,估计被人唬住。然而其本质原因是忽略表中的数据特征,一味地自发想象预期美好,不切实际分析问题。
在这里插入图片描述


二、探索之路

2.1 数据准备

drop table if exists test01;
drop table if exists test02;
create table test01 (c1 int, c2 int , c3 int);
create table test02 (d1 int, d2 int , d3 int);

insert into test01 values(1, 10, 11);
insert into test01 values(2, null, 12);
insert into test01 values(3, null, 13);
insert into test01 values(4, null, 14);

insert into test02 values(1, null, 11);
insert into test02 values(2, 20, 12);
insert into test02 values(3, 30, 13);
insert into test02 values(4, 40, 14);
commit;

2.2 回顾NULL表达式

解释:NULL在数据库是一个特殊的存在,不是具体数据(暂时无法确定具体值,可能后期会赋予具体意义的值),属于一个抽象的占位符,表示某类型的未知数据,可以理解为数学方程式中的X(未知数,不确定性值)。


当然针对NULL的判断,数据库有专门的运算符比较,即IS NULL 或IS NOT NULL,而不是 = 、<>、 != 常规运算符,则遇见非IS NULL/IS NOT NULL的普通比较表达式,结果永远是false。请记住这个理论。

-- 举例1:判断某表某列非空有哪些记录
-- 正确写法
select * from test01 where c2 is not null;
select * from test01 where not c2 is null;
select * from test01 where nvl(c2, '<NA!>') != '<NA!>' ;
select * from test01 where coalesce(c2, '<NA!>') != '<NA!>' ;
select * from test01 where isnull(c2, '<NA!>') != '<NA!>' ;
select * from test01 where ifnull(c2, '<NA!>') != '<NA!>' ;
select * from test01 where decode(c2, null, 0, 1) = 1;
select * from test01 where lnnvl(c2 is null);
select * from test01 where c2 > 0;  -- 知道该表C2字段数值分布,等效的写法

-- 错误写法(返回空结果集)
select * from test01 where c2 != null;
select * from test01 where c2 <> null;


-- 普通比较运算永远false(返回空结果集)
select * from test01 where c2 = null;
select * from test01 where c2 > null;
select * from test01 where c2 < null;

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


2.3 重现问题

模拟问题引入环节所说的场景,两表关联

select count(*) -- 0
from test01 t1 
inner join test02 t2 on  t1.c1 = t2.d1
where t1.c2 = t2.d2; 


select count(*) -- 0
from test01 t1 
inner join test02 t2 on  t1.c1 = t2.d1
where t1.c2 != t2.d2; 

在这里插入图片描述

在这里插入图片描述

2.3.1 分析原因
select t1.*, t2.* 
from test01 t1 
inner join test02 t2 on  t1.c1 = t2.d1;

在c1=d1等值关联条件成立情况下,进一步二级关联条件C2 = D2 或 C2 <> D2 ,从下图可知每次两表对二级关联条件匹配时存在一个NULL值,无论=、!= 比较运算,二级关联表达式永远false,导致最终结果集为空,正如count统计为零。

在这里插入图片描述

在这里插入图片描述

2.3.2 如何化解预期?

按他的预想是包含二级关联条件时存在NULL的情况,所以因在where过滤条件加入IS NULL判断。

select t1.*, t2.* 
from test01 t1 
inner join test02 t2 on  t1.c1 = t2.D1
where t1.c2 = t2.d2 or t1.c2 is null or t2.d2 is null; 

select count(*) -- 4
from test01 t1 
inner join test02 t2 on  t1.c1 = t2.d1
where t1.c2 = t2.d2 or t1.c2 is null or t2.d2 is null;

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


三、知识总结

1)编写SQL未按预期执行,应先思考SQL逻辑是否得当?再观察数据本身特征,不能盲目自认为。
2)SQL当中NULL往往易遗忘,正由它的特殊性存在,一旦未考虑全面,有可能结果集是非预期(可能遗漏有效数据或增多无效数据)。
3)建议数据表设定default默认值属性,减少NULL比较的可能性,减轻脑仁的负荷运转。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938539.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu22.04安装docker desktop遇到的bug

1. 确认已启用 KVM 虚拟化 如果加载了模块&#xff0c;输出应该如下图。说明 Intel CPU 的 KVM 模块已开启。 否则在VMware开启宿主机虚拟化功能&#xff1a; 2. 下一步操作&#xff1a; Ubuntu | Docker Docs 3. 启动Docker桌面后发现账户登陆不上去&#xff1a; Sign in | …

JVM(Java虚拟机)的虚拟机栈

JVM&#xff08;Java虚拟机&#xff09;的虚拟机栈是Java程序运行时的重要组件&#xff0c;以下是对其的详细解析&#xff1a; 一、概念与功能 概念&#xff1a;虚拟机栈也称为Java栈&#xff0c;是JVM为每个线程分配的一个私有的内存区域。每个线程在创建时都会创建一个虚拟…

集成自然语言理解服务,让应用 “听得懂人话”

如今&#xff0c;应用程序智能化已成趋势&#xff0c;开发者想要实现智能化&#xff0c;那么首先需要赋予应用理解自然语言的能力&#xff0c;使其能够准确地听懂人话&#xff0c;进而响应用户需求&#xff0c;并提供一系列智能化服务。比如用户语音控制应用程序帮忙订票&#…

Springboot3.x配置类(Configuration)和单元测试

配置类在Spring Boot框架中扮演着关键角色&#xff0c;它使开发者能够利用Java代码定义Bean、设定属性及调整其他Spring相关设置&#xff0c;取代了早期版本中依赖的XML配置文件。 集中化管理&#xff1a;借助Configuration注解&#xff0c;Spring Boot让用户能在一个或几个配…

fabric.js

目录 一、在canvas上画简单的图形 二、在canvas上用路径(Path)画不规则图形 三、在canvas上插入图片并设置旋转属性(angle) 四、让元素动起来(animate) 五、图像过滤器(filters)让图片多姿多彩 六、颜色模式(Color)和相互转换(toRgb、toHex) 七、对图形的渐变填充(Gradi…

ActiveMQ 反序列化漏洞CVE-2015-5254复现

文章目录 一、产生原因二、利用条件三、利用过程四、PoC&#xff08;概念验证&#xff09;五、poc环境验证使用find搜索vulhub已安装目录打开activeMQ组件查看配置文件端口启动镜像-文件配置好后对于Docker 镜像下载问题及解决办法设置好镜像源地址&#xff0c;进行重启docker查…

给新ubuntu电脑配置远程控制环境和c++版本的opencv环境

目录 改用户密码安装ssh sever安装net-tools配置vscode安装vim配置C opencv1. 安装g, cmake, make2.安装opencv依赖库3.下载opencv源文件&#xff08;1&#xff09;方法一&#xff1a;官网下载&#xff08;2&#xff09;方法二&#xff1a;GitHub下载方式&#xff1a; 4. Cmake…

如何在 Debian 12 上安装和使用 Vuls 漏洞扫描器

简介 Vuls 是一款无代理、免费且开源的 Linux 和 FreeBSD 漏洞扫描器。Vuls 主要用 Go 语言编写&#xff0c;可以在任何地方运行。你可以在云端、本地和 Docker 上运行 Vuls&#xff0c;并且它支持主要的发行版。Vuls 提供高质量的扫描&#xff0c;支持多个漏洞数据库&#xf…

Python-装饰器(Decorator)详解

在python中&#xff0c;函数是一等公民&#xff0c;意味着函数可以像其他对象一样被赋值、传递参数、作为返回值等。装饰器的基本语法是使用符号将一个函数作为参数传递给另一个函数&#xff08;即装饰器&#xff09;。被装饰的函数在被调用时&#xff0c;实际上会执行装饰器函…

数据结构_拓扑排序

拓扑排序 &#xff08;所有点按照先后顺序排序&#xff09; 1.先找到入度为0的点&#xff0c;记录之后&#xff0c;删除这个点和它的出边&#xff1b; 2.若有两个可选&#xff0c;随便选择一个 例 a的入度为0,选a [a] 随便选一个 [a,e] 再找入度为0的点 再选c 最后选d 拓…

MinerU:PDF文档提取工具

目录 docker一键启动本地配置下载模型权重文件demo.py使用命令行启动GPU使用情况 wget https://github.com/opendatalab/MinerU/raw/master/Dockerfile docker build -t mineru:latest .docker一键启动 有点问题&#xff0c;晚点更新 本地配置 就是在Python环境中配置依赖和…

redis集群安装部署 redis三主三从集群

redis集群安装部署 redis三主三从集群 1、下载redis2、安装redis集群 三主三从3、配置redis开机自启动3.1、建立启动脚本3.2、复制多份redis启动脚本给集群使用3.3、添加可执行权限3.4、配置开机自启动 1、下载redis 本次redis安装部署选择当前最新的稳定版本7.4.1 下载链接: …

Fiddler简单使用

Fiddler使用方法 1.作用 接口测试&#xff0c;发送自定义请求&#xff0c;模拟小型的接口测试定位前后端bug&#xff0c;抓取协议包&#xff0c;前后端联调构建模拟测试场景&#xff0c;数据篡改&#xff0c;重定向弱网测试&#xff0c;模拟限速操作&#xff0c;弱网&#xf…

203.PyQt5_QTreeWidget_项处理_树形结构

课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)教程合集 👈👈…

6.2 MapReduce工作原理

MapReduce工作原理涉及将大数据集分割成小块并行处理。Map任务读取数据块并输出中间键值对&#xff0c;而Reduce任务则处理这些排序后的数据以生成最终结果。MapTask工作包括读取数据、应用Map函数、收集输出、内存溢出时写入磁盘以及可选的Combiner局部聚合。ReduceTask工作则…

【线性代数】理解矩阵乘法的意义(点乘)

刚接触线性代数时&#xff0c;很不理解矩阵乘法的计算规则&#xff0c;为什么规则定义的看起来那么有规律却又莫名其妙&#xff0c;现在参考了一些资料&#xff0c;回过头重新总结下个人对矩阵乘法的理解&#xff08;严格来说是点乘&#xff09;。 理解矩阵和矩阵的乘法&#x…

Win11安装安卓子系统WSA

文章目录 简介一、启用Hyper-V二、安装WSA三、安装APKAPK商店参考文献 简介 WSA&#xff1a;Windows Subsystem For Android 一、启用Hyper-V 控制面板 → 程序和功能 → 启用或关闭 Windows 功能 → 勾选 Hyper-V 二、安装WSA 进入 Microsoft Store&#xff0c;下拉框改为 …

Tree-of-Counterfactual Prompting for Zero-Shot Stance Detection

论文地址&#xff1a;Tree-of-Counterfactual Prompting for Zero-Shot Stance Detection - ACL Anthologyhttps://aclanthology.org/2024.acl-long.49/ 1. 概述 立场检测被定义为对文本中立场态度的自动推断。根据 Biber 和 Finegan (1988) 的定义&#xff0c;立场包含两个主…

轻松上手:使用 Vercel 部署 HTML 页面教程

&#x1f600; 在学习前端的过程中&#xff0c;部署项目往往是一个令人头疼的问题。然而&#xff0c;Vercel 为我们提供了一个便捷且免费的解决方案。 Vercel 是一个强大的云平台&#xff0c;专门用于前端项目的部署和托管。它不仅支持多种前端框架和静态网站生成器&#xff0…

QT从入门到精通(二) ——信号与槽机制

Qt 的信号与槽机制&#xff08;Signal and Slot&#xff09;是 Qt 框架 中用于对象间通信的核心机制之一。它允许对象之间进行松耦合的事件驱动式通信&#xff0c;尤其适合 GUI 应用程序 中的事件处理。 1. 基本概念 信号 (Signal) 当对象的状态发生变化时&#xff0c;它会发…