NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

如何正确理解 SQL 中的 NULL

  • 2020-04-01
  • 本文字数:1811 字

    阅读完需:约 6 分钟

如何正确理解SQL中的NULL

在查询数据库时,如果你想知道一个列是否为 NULL,SQL 查询语句该怎么写呢?


是不是这样:


SELECT * FROM SOME_TABLEWHERE SOME_COLUMN = NULL
复制代码


或者这样写:


SELECT * FROM SOME_TABLEWHERE SOME_COLUMN IS NULL
复制代码


正确的写法应该是第二种(WHERE SOME_COLUMN IS NULL)。


为什么要这样写?


在进行数据库数据比较操作时,我们不会使用“IS”关键词,不是吗?


例如,如果我们想要知道一个列的值是否等于 1,WHERE 语句是这样的:


WHERE SOME_COLUMN = 1
复制代码


那为什么 NULL 值要用 IS 关键字呢?为什么要以这种方式来处理 NULL?


因为,在 SQL 中,NULL 表示“未知”。也就是说,NULL 值表示的是“未知”的值。

NULL 等于未知

在大多数数据库中,NULl 和空字符串是有区别的。


但并不是所有数据库都这样,例如,Oracle 就不支持空字符串,它会把空字符串自动转成 NULL 值。


在其他大多数数据库里,NULL 值和字符串的处理方式是不一样的:


  • 空字符串表示“没有值”,这个值是已知的。

  • NULL 表示“未知值”,这个值是未知的。


这就好比我问了一个问题:“美国总统罗斯福的中间名是什么”?


  • 可能有人会回答说:“我不知道罗斯福总统的中间名是什么”。对于这种情况,可以在数据库中使用 MIDDLE_NAME 列来表示罗斯福的中间名,而这一列的值为 NULL。

  • 也可能有人会回答说:“罗斯福总统没有中间名。他的父母没有给他取中间名,所以我知道罗斯福总统确实没有中间名”。对于这种情况,MIDDLE_NAME 列应该是一个空字符串。


Oracle 比较特殊,两个值都使用 NULL 来表示,而其他大多数数据库会区分对待。


但只要记住 NULL 表示的是一个未知的值,那么在写 SQL 查询语句时就会得心应手。


例如,如果你有一个这样的查询语句:


SELECT * FROM SOME_TABLEWHERE 1 = 1
复制代码


这个查询会返回所有的行(假设 SOME_TABLE 不是空表),因为表达式“1=1”一定为 true。


如果我这样写:


SELECT * FROM SOME_TABLEWHERE 1 = 0
复制代码


表达式“1=0”是 false,这个查询语句不会返回任何数据。


但如果我写成这样:


SELECT * FROM SOME_TABLEWHERE 1 = NULL
复制代码


这个时候,数据库不知道这两个值(1 和 NULL)是否相等,所以它也不会返回任何数据。

三元逻辑

SQL 查询语句中的 WHERE 一般会有三种结果:


  • 它可以是 true(这个时候会返回数据);

  • 它可以是 false(这个时候不会返回数据);

  • 它也可以是 NULL 或未知(这个时候也不会返回数据)。


你可能会想:“既然这样,那我为什么要去关心是 false 还是 NULL?它们不是都不会返回数据吗?”


接下来,我来告诉你在哪些情况下会有问题:我们来看看 NOT()。


假设有这样的一个查询语句:


SELECT * FROM SOME_TABLEWHERE NOT(1 = 1)
复制代码


数据库首先会计算 1=1,这个显然是 true。


接着,数据库会应用 NOT() 条件,所以 WHERE 返回 false。


所以,上面的查询不会返回任何数据。


但如果把语句改成这样:


SELECT * FROM SOME_TABLEWHERE NOT(1 = 0)
复制代码


数据库首先会计算 1=0,这个肯定是 false。


接着,数据库应用 NOT() 条件,这样就得到相反的结果,变成了 true。


所以,这个语句会返回数据。


但如果把语句再改成下面这样呢?


SELECT * FROM SOME_TABLEWHERE NOT(1 = NULL)
复制代码


数据库首先计算 1=NULL,它不知道 1 是否等于 NULL,因为它不知道 NULL 的值是什么。


所以,这个计算不会返回 true,也不会返回 false,它会返回一个 NULL。


接下来,NOT() 会继续解析上一个计算返回的结果。


当 NOT() 遇到 NULL,它会生成另一个 NULL。未知的相反面是另一个未知。


所以,对于这两个查询:


SELECT * FROM SOME_TABLEWHERE NOT(1 = NULL)
复制代码



SELECT * FROM SOME_TABLEWHERE 1 = NULL
复制代码


都不会返回数据,尽管它们是完全相反的。

NULL 和 NOT IN

如果我有这样的一个查询语句:


SELECT * FROM SOME_TABLEWHERE 1 IN (1, 2, 3, 4, NULL)
复制代码


很显然,WHERE 返回 true,这个语句将返回数据,因为 1 在括号列表里是存在的。


但如果这么写:


SELECT * FROM SOME_TABLEWHERE 1 NOT IN (1, 2, 3, 4, NULL)
复制代码


很显然,WHERE 返回 false,这个查询不会返回数据,因为 1 在括号列表里存在,但我们说的是“NOT IN”。


但如果我们把语句改成这样呢?


SELECT * FROM SOME_TABLEWHERE 5 NOT IN (1, 2, 3, 4, NULL)
复制代码


这里的 WHRE 不会返回数据,因为它的结果不是 true。数字 5 在括号列表里可能不存在,也可能存在,因为当中有一个 NULL 值(数据库不知道 NULL 的值是什么)。


这个 WHERE 会返回 NULL,所以整个查询不会返回任何数据。


希望你们现在都清楚该怎么在 SQL 语句中处理 NULL 值了。

英文原文

Null Values in SQL Queries


2020-04-01 14:152308
用户头像
小智 让所有人认同的文字称不上表达

发布了 408 篇内容, 共 377.4 次阅读, 收获喜欢 1972 次。

关注

评论 1 条评论

发布
用户头像
涨姿势了,以前确实没有好好思考过null的问题
2020-04-01 23:44
回复
没有更多了
发现更多内容

1月月更|推荐学java——Spring之AOP

逆锋起笔

spring SSM框架 spring aop 依赖注入 面向切面编程

Hive SQL底层执行原理

五分钟学大数据

Hive SQL 1月月更

TDSQL-C for PostgreSQL 主从架构详解

腾讯云数据库

tdsql 国产数据库

组件通信、硬件池化,这些创新技术你get了吗?|HDC2021技术分论坛

HarmonyOS开发者

HarmonyOS

Chrome插件:摸鱼倒计时、每日摸鱼时间统计,奋斗逼、卷王必备,用于减少摸鱼时间和频率

OBKoro1

效率 开源 效率工具 chrome扩展 高效率

ReactNative进阶(二十三):Javascript 严格模式详解

No Silver Bullet

React Native 1月月更

Serverless 背景下,一部分“前端工程师”会转变为“应用交付工程师”

杨成功

Serverless 架构 前端

创业老兵李峻的新征程|ONES 人物

万事ONES

Jetpack—LiveData组件的缺陷以及应对策略

vivo互联网技术

android livedata JetPack 移动应用开发

使用php-amqplib实现RabbitMq

Owen Zhang

php RabbitMQ php-amqplib

虎符研究院深入解读Web3.0未来趋势 盘点代表性项目

区块链前沿News

Web Hoo虎符 虎符研究院 虎符平台 3.0

我相信:没有解不开的难题|ONES 人物

万事ONES

龙蜥社区一周动态 | 1.10-1.14

OpenAnolis小助手

Linux 开源 社群

CSS 自适应内容宽度的输入框

编程江湖

我以订披萨为例,给女朋友详细讲了Java设计模式的3种工厂模式

华为云开发者联盟

Java 工厂模式 工厂方法模式 简单工厂模式 抽象工厂模式

TDSQL PG版企业级分布式数据库技术创新实践

腾讯云数据库

tdsql 国产数据库

java开发之Redis的使用规范

@零度

redis JAVA开发

前端使用 zx 库在 Node 中编写 Shell 脚本

devpoint

node.js Shell 1月月更 zx.js

知识库进化论 | 华创资本对话 ONES & 为知笔记创始人

万事ONES

MySQL分区表简介

soap said

:MySQL 数据库

大数据开发之通过 Spark 来扩展 Presto

@零度

大数据 spark

线上流量对比应用实践

得物技术

架构 数据 流量 实践 流量回放

Hadoop小文件问题产生及解决方案

五分钟学大数据

hadoop 1月月更

软件设计——依赖倒置

苏州程序大白

架构师

ONES CTO 冯斌|如何低成本地做出高质量决策

万事ONES

2021 OceanBase 开源半年度报告 | 不忘初心,感恩同行

OceanBase 数据库

开发者 报告 OceanBase 开源 OceanBase 社区版

前端开发之JQuery的综合应用

@零度

jquery 前端开发

Android技术分享| 自定义View实现使用更方便的SeekBar

anyRTC开发者

android 音视频 移动开发 白板 SeekBar

Scrum Master需要具备哪些能力和经验

华为云开发者联盟

Scrum 敏捷 团队 教练 Scrum Master

GIS :元宇宙未来发展的有力技术支撑

华为云开发者联盟

AI GIS 虚拟世界 数字孪生 云宇宙

TDSQL | 将企业级分布式数据库做到极致

腾讯云数据库

tdsql 国产数据库

如何正确理解SQL中的NULL_数据库_MITCHUM_InfoQ精选文章