当前位置: 首页 > news >正文

SparkSQL 子查询 IN/NOT IN 对 NULL 值的处理

SparkSQL 子查询 IN/NOT IN 对 NULL 值的处理

官网:https://spark.apache.org/docs/4.0.0/sql-ref-functions.html

https://spark.apache.org/docs/4.0.0/sql-ref-null-semantics.html#innot-in-subquery

在这里插入图片描述

Unlike the EXISTS expression, IN expression can return a TRUE, FALSE or UNKNOWN (NULL) value.
EXISTS 不同,IN 表达式可能返回三种布尔状态:

  • TRUE:当前值在集合中;
  • FALSE:当前值不在集合中;
  • UNKNOWN(即 NULL):当表达式中涉及了 NULL 值时,无法确定真假。

Conceptually a IN expression is semantically equivalent to a set of equality condition separated by a disjunctive operator (OR).For example, c1 IN (1, 2, 3) is semantically equivalent to (c1 = 1 OR c1 = 2 OR c1 = 3).

从语义上讲,IN 表达式等价于多个等于条件用 OR 连接起来。

c1 IN (1, 2, 3)

相当于:

c1 = 1 OR c1 = 2 OR c1 = 3

As far as handling NULL values are concerned, the semantics can be deduced from the NULL value handling in comparison operators(=) and logical operators(OR).

对于 NULL 值的处理方式,可以基于比较运算符(如 =)和逻辑运算符(如 OR)的行为来推导。 也就是说,IN 的行为是建立在底层 SQL 对 NULL 处理规则之上的。


To summarize, below are the rules for computing the result of an IN expression.

  • TRUE is returned when the non-NULL value in question is found in the list
  • FALSE is returned when the non-NULL value is not found in the list and the list does not contain NULL values
  • UNKNOWN is returned when the value is NULL, or the non-NULL value is not found in the list and the list contains at least one NULL value

IN 表达式的计算规则如下:

情况结果
当前值不为 NULL,并且存在于列表中TRUE
当前值不为 NULL,但不在列表中,且列表中没有 NULL值FALSE
当前值为 NULL,或者列表中有 NULL值但当前值不在其中UNKNOWN

只要列表中包含 NULL,即使当前值不在列表中,也不能简单地返回 FALSE,而是返回 UNKNOWN


IN Demo:


1:子查询结果只有 NULL

%sql
WITH person AS (SELECT * FROM VALUES('a', 25),('b', 30),('c', 35),('d', 40),('e', 50),('d', 50)AS person(name, age)
)
SELECT * FROM person
WHERE age IN (SELECT null);

空表✅

在这里插入图片描述

  • IN (NULL) 返回的是 UNKNOWN,不会匹配任何行。

2:子查询包含 NULL 和有效值

%sql
WITH person AS (SELECT * FROM VALUES('a', 25),('b', 30),('c', 35),('d', 40),('e', 50),('f', 50)AS person(name, age)
)
SELECT * FROM person
WHERE age IN (SELECT age FROM VALUES(50), (NULL)AS sub(age)
);
-- 虽然子查询里有 NULL,但只要匹配到具体值就会返回;

只有 age = 50 的记录被选中。

在这里插入图片描述


3:子查询包含 NULL 和多个值

%sql
WITH person AS (SELECT * FROM VALUES('a', 25),('b', 30),('c', 35),('d', 40),('e', 50),('f', 50)AS person(name, age)
)
SELECT * FROM person
WHERE age IN (SELECT age FROM VALUES(25), (30), (NULL)AS sub(age)
);
-- 虽然子查询里有 NULL,但只要匹配到具体值就会返回;

在这里插入图片描述


4: 主表中存在 NULL 值,同时子查询结果也包含 NULL

在这里插入图片描述

条件是否被选中原因
age = 25✅ 是匹配列表中的值
age = NULL❌ 否NULL IN (…) → UNKNOWN
age = 35/40/50❌ 否不匹配列表中的非 NULL 值,且列表中有 NULL → UNKNOWN

NOT IN Demo:

只要 NOT IN 后面的子查询包含 NULL,整个条件就会变成 UNKNOWN没有任何行被返回

避免这个问题,需要在子查询中加上 WHERE age IS NOT NULL

1:子查询结果只有 NULL

  • NOT IN (只要有null)不返回任何结果
%sql
WITH person AS (SELECT * FROM VALUES('a', 25),('b', 30),('c', 35),('d', 40),('e', 50),('d', 50)AS person(name, age)
)
SELECT * FROM person
WHERE age NOT IN (SELECT null);

在这里插入图片描述

子查询中包含 NULLNOT IN 整体返回 UNKNOWN,SQL 不会将其视为 TRUE,所以没有行满足条件。


2: 子查询包含 NULL 和有效值

  • NOT IN (只要有null)不返回任何结果
%sql
WITH person AS (SELECT * FROM VALUES('a', 25),('b', 30),('c', 35),('d', 40),('e', 50),('f', 50)AS person(name, age)
)
SELECT * FROM person
WHERE age NOT IN (SELECT age FROM VALUES(50), (NULL)AS sub(age)
);

在这里插入图片描述


3: 主表中存在 NULL 值,同时子查询结果也包含 NULL

  • NOT IN (只要有null)不返回任何结果
%sql
WITH person AS (SELECT * FROM VALUES('a', 25),('b', 30),('c', null),('d', 40),('e', 50),('f', 50)AS person(name, age)
)
SELECT * FROM person
WHERE age NOT IN (SELECT age FROM VALUES(50), (NULL)AS sub(age)
);

在这里插入图片描述


Spark官方对于各种函数处理null值的说明:

https://spark.apache.org/docs/4.0.0/sql-ref-null-semantics.html

在这里插入图片描述

http://www.lryc.cn/news/598330.html

相关文章:

  • 数据结构 堆(3)---堆排序
  • 在 Windows 上安装设置 MongoDB及常见问题
  • 多源信息融合智能投资【“图神经网络+强化学习“的融合架构】【低配显卡正常运行】
  • 如何清理电脑c盘内存 详细操作步骤
  • dify 变量聚合器-聚合分组问题
  • 【Java工程师面试全攻略】Day12:系统安全与高可用设计
  • 再生基因总结
  • 腾势N9再进化:智能加buff,豪华更对味
  • Dataease2.10 前端二次开发
  • Java 实现 C/S 架构详解:从基础到实战,彻底掌握客户端/服务端编程
  • 机器学习的基础知识
  • LeetCode 2563.统计公平数对的数目
  • AI时代,我的编程工作搭子
  • Windows 主机侧日志排查
  • CentOS7 安装 rust 1.82.0
  • 小模数齿轮的加工方法有哪些?
  • 医疗系统国产化实录:SQL Server国产替代,乙方保命指南
  • MySQL 表的操作
  • 【Haproxy】七层代理
  • 详解力扣高频SQL50题之1683. 无效的推文【入门】
  • MySQL深度理解-MySQL事务优化
  • SQL173 店铺901国庆期间的7日动销率和滞销率
  • 详解力扣高频SQL50题之197. 上升的温度【简单】
  • 【MySQL】MySQL 事务和锁详解
  • Redis--哨兵机制详解
  • day20 双向链表
  • 适配器模式——以springboot为例
  • RK3568笔记九十一:QT环境搭建
  • 【Java基础06】ArrayList
  • AudioLLM 开源项目了解学习