写点什么

如何正确理解 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:152653
用户头像
小智 让所有人认同的文字称不上表达

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

关注

评论 1 条评论

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

Go 项目自动重载解决方案 —— Air 使用入门

左诗右码

Go

lazada商品详情数据接口(lazada.item_get)丨lazada平台API接口指南

tbapi

lazada商品详情数据接口 lazada API lazada商品数据采集

千帆大模型平台升级十大能力,企业级 RAG 全面升级

Baidu AICLOUD

千帆大模型平台 rag

飞书邀请ToB伙伴们一起共建“生态绿洲”!

ToB行业头条

从0到100:4S店服务小程序开发历程

CC同学

集业界领袖,话数据库未来,华为云数据库斯享会深圳站成功举办

极客天地

闲鱼商品详情数据接口(Goodfish.item_get)丨闲鱼平台实时数据接口指南

tbapi

闲鱼 闲鱼API 闲鱼商品详情接口 闲鱼商品详情数据采集

京东工业平台商品详情数据接口(vipmro.item_get)丨京东工业平台数据API

tbapi

京东工业平台数据采集 京东工业平台 京东工业平台API接口

聊聊 Go 中的单例模式

左诗右码

Go

百度网盘上线Apple Vision Pro 国行版迎来首个AI云存储类产品!

IT新闻资讯

证券行业怎么定义,需要采购堡垒机吗?

行云管家

网络安全 金融 证券 数据安全 堡垒机

深入理解JVM:内存管理与垃圾回收机制探索

乘云数字DataBuff

JVM 内存

AI Agent技术的最新进展与改变世界的典型项目巡礼

汀丶人工智能

人工智能 大模型 Agent智能体

AI 应用实战营 - 作业 三- MidJourney参数测试

德拉古蒂洛维奇

目前张家界正规等保测评机构有几家?在哪里?

行云管家

等保 等级保护 湖南 张家界

深耕分析型数据库领域,火山引擎ByteHouse入围《2024爱分析数据库厂商全景报告》

字节跳动数据平台

数据库 大数据 云原生 bytehouse Click house

性能测试:行业流行性能剖析工具介绍

测试人

软件测试

三连冠!百度文库再次登顶AI产品榜

极客天地

阿里巴巴商品详情数据接口(alibaba.item_get)丨阿里巴巴API实时数据接口指南

tbapi

阿里巴巴 阿里巴巴商品详情数据接口 阿里巴巴API

小米集团信息技术部|面向多业务的研发效能体系建设与实践

ToB行业头条

“小浣熊家族AI办公助手”产品体验 — “人人都是数据分析师”

Sunny_媛

#人工智能 AI Agent 小浣熊家族 小浣熊 AI办公助手

开源数据库Greenplu突然闭源?GaussDB(DWS)提供数仓新可能

华为云开发者联盟

数据库 postgresql 华为云 华为云开发者联盟 企业号2024年7月PK榜

软件测试学习笔记丨JUnit5自定义动态测试的执行顺序

测试人

软件测试

纺织业智能化与数字化转型:构建全流程智能物流与质量追溯体系

天津汇柏科技有限公司

数字化转型 纺织企业

快手商品详情数据接口(KS.item_get)丨快手API接口指南

tbapi

快手 快手商品详情数据接口 快手API接口

ICE启动AI:人工智能高频交易平台测试进入尾段

科技汇

ICE启动AI:人工智能高频交易平台测试进入尾段

科技热闻

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