如果子查询包含 NULL,带有“IN”子查询的 SQL select 不会返回任何记录

2024-07-01

我遇到了这个有趣的行为。我认为左连接是可行的方法,但仍然希望解决这个问题。这是错误还是设计行为?有什么解释吗?

当我从左表中选择记录时,右表的子查询结果中不存在值,如果子查询结果有空值,则不会返回预期的“缺失”记录。我希望编写此查询的两种方法是等效的。

Thanks!

declare @left table  (id int not null primary key identity(1,1), ref int null)
declare @right table (id int not null primary key identity(1,1), ref int null)

insert @left (ref) values (1)
insert @left (ref) values (2)

insert @right (ref) values (1)
insert @right (ref) values (null)

print 'unexpected empty resultset:'
select * from @left
where ref not in (select ref from @right)

print 'expected result - ref 2:'
select * from @left
where ref not in (select ref from @right where ref is not null)

print 'expected result - ref 2:'
select l.* from @left l
  left join @right r on r.ref = l.ref
where r.id is null

print @@version

gives:

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)
unexpected empty resultset:
id          ref
----------- -----------

(0 row(s) affected)

expected result - ref 2:
id          ref
----------- -----------
2           2

(1 row(s) affected)

expected result - ref 2:
id          ref
----------- -----------
2           2

(1 row(s) affected)

Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) 
    Apr  2 2010 15:48:46 
    Copyright (c) Microsoft Corporation
    Standard Edition (64-bit) on Windows NT 6.0 <X64> (Build 6002: Service Pack 2) (Hypervisor)

这是设计使然。如果匹配失败并且集合包含 NULL,则结果为 NULL,如 SQL 标准所指定。



'1' IN ('1', '3') => true
'2' IN ('1', '3') => false
'1' IN ('1', NULL) => true
'2' IN ('1', NULL) => NULL

'1' NOT IN ('1', '3') => false
'2' NOT IN ('1', '3') => true
'1' NOT IN ('1', NULL) => false
'2' NOT IN ('1', NULL) => NULL
  

通俗地说,其背后的逻辑是 NULL 可以被认为是一个未知值。例如,这里未知值是什么并不重要 - '1' 显然在集合中,所以结果是 true。

'1' IN ('1', NULL) => true

在下面的示例中,我们无法确定“2”是否在集合中,但由于我们不知道所有值,因此我们也无法确定它是否在集合中isn't在集合中。所以结果是NULL。

'2' IN ('1', NULL) => NULL

另一种看待它的方法是重写x NOT IN (Y, Z) as X <> Y AND X <> Z。然后你可以使用以下规则三值逻辑 http://en.wikipedia.org/wiki/Null_%28SQL%29#Three-valued_logic_.283VL.29:

true AND NULL => NULL
false AND NULL => false
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果子查询包含 NULL,带有“IN”子查询的 SQL select 不会返回任何记录 的相关文章

随机推荐

  • WiFiManager - 绊脚石

    我尝试使用 iphone os 2 0 和 3 0 使用 stumbler 获取 ssid 但出现错误 发现缺少一些框架 谁能告诉我如何恢复 我发现 StackOverflow 上有一篇文章提到 PrivateFrameworks Appl
  • 我需要将链接服务器添加到 MS Azure SQL Server

    我试了又试 还是无法链接 我可以使用 SSMS 连接到服务器 但无法从本地服务器链接到它 这是我的脚本 用相关信息替换括号中的内容 EXEC master dbo sp addlinkedserver server N servername
  • 如何获取mp3曲目的时长?

    我想问一下如何在应用程序中获取音频文件的长度 我正在像这样加载曲目 var installFolder Windows ApplicationModel Package Current InstalledLocation var resou
  • 在容器大小调整时调整传单地图的大小

    我有一个 div 包含传单地图 在某些事件发生时 高度 div 将会被改变 我希望地图能够调整到其周围的新尺寸 div 以便旧中心位于调整大小的较小或较大地图的中心 我尝试使用invalidateSize 功能 但似乎根本不起作用 之后如何
  • 使用 Git 在本地保存文件的不同版本与在主存储库中保存文件的不同版本

    我有一个 PHP 配置文件 我想在本地操作 但忽略期间的这些更改git commits到我的主存储库 我曾有一个 gitignore文件曾经忽略这个 PHP 文件 但发生了不好的事情 现在config php文件不再被忽略 我不记得如何重新
  • 使用 node/pino 记录到 STDOUT 和文件

    我分享这个是因为我努力让 pino 记录器写入 STDOUT 和日志文件 const dest new stream PassThrough dest pipe process stdout dest pipe fs createWrite
  • 在 Android Studio 中重命名包

    我正在尝试重命名我的 Android Studio 包 如第一个答案中所述 Android Studio重命名包 https stackoverflow com questions 16804093 android studio renam
  • Sphinx搜索如何使用空的before_match和after_match

    使用狮身人面像片段 http sphinxsearch com docs current html sphinxql select功能 我怎样才能删除任何before match and after match从我的查询 我不希望匹配文本周
  • 将 std::lock_guard 与 try_lock 一起使用

    有什么办法可以告诉我std lock guard打电话try lock代替lock当它获取互斥锁时 我能想到的唯一方法是使用std adopt lock if mutex try lock Handle failure and return
  • 一个类的多个实例

    我正在尝试用 python 编写各种动物的生活模拟 不可能命名我将要使用的类的每个实例 因为我无法知道会有多少个实例 所以 我的问题是 如何自动为对象命名 我正在考虑创建一个 Herd 类 它可以是该类型的所有动物同时存活 嗯 通常 您只需
  • 解释 Spark Structured Streaming 执行器和 Kafka 分区之间的映射

    我已经在具有 4 个分区的 Kafka 主题上部署了一个由 4 个工作人员组成的结构化流 我假设将为 4 个分区部署 4 个工作人员 工作人员 分区之间具有一对一的映射 但是 事实并非如此 所有分区都由同一个执行器提供服务 我通过检查执行器
  • Asp.Net Mvc 5 图像不显示

    我有相同的图像Content and Views文件夹 我正在尝试显示图像 如下所示 img src Content Images download png alt Content folder br br img src Views Ho
  • PyCharm 中基于类型的自动补全

    我正在使用 PyCharm 进行 python 编码 PyCharm 中的自动完成功能不如 IntelliJ Java 中的自动完成功能 考虑下面的代码 a 1 2 3 4 a 在这种情况下 当我按下dot PyCharm 提供了全套自动完
  • WPF DataGrid 在行删除后失去焦点

    我正在使用 WPF DataGrid 通过键盘 删除 键进行行删除 但是 删除该行后 DataGrid 失去焦点 并且 DataGrid SelectedIndex 1 与WinForm datagrid相比 删除一行后 焦点自动转移到下一
  • static const 和 constexpr 变量有什么区别? [复制]

    这个问题在这里已经有答案了 我明白 一个constexpr variable可以在编译时使用 对于模板 或者例如 static assert 但如果我想在没有 constexpr 的情况下做到这一点 我可以static const 自从 C
  • 为什么 IE7 不能正确地将
     块复制到剪贴板?                
                

    我们注意到 IE7 对 Stack Overflow 上发布的代码块有奇怪的行为 例如 这个小代码块 public PageSizer string href int index HRef href PageIndex index 从IE7
  • 如何在嵌入 UIViewController 的 UITableView 中直观地创建和使用静态单元格

    我正在使用 XCode 4 2 并使用故事板构建了我的 UI 我需要创建一个在 UITableView 上方和下方有内容的视图 我可以通过使用 UIViewController 来实现这一点 UITableViewController 不允
  • 如何在远程 shell 上接收 stdio 和 error_logger 消息

    在花了很长时间让 rb 在远程 shell 上工作后 我想在远程 shell 上获取 stdio 错误记录器消息 我已经研究了更改 group leader 但似乎需要更改所有正在运行的进程的 group leader 我的实验发现它非常不
  • VB.NET GetElementById 内部文本

    好的 这是我的 html 行及其 ID
  • 如果子查询包含 NULL,带有“IN”子查询的 SQL select 不会返回任何记录

    我遇到了这个有趣的行为 我认为左连接是可行的方法 但仍然希望解决这个问题 这是错误还是设计行为 有什么解释吗 当我从左表中选择记录时 右表的子查询结果中不存在值 如果子查询结果有空值 则不会返回预期的 缺失 记录 我希望编写此查询的两种方法