Lun*_*tri 2 sql t-sql sql-server null
我偶然发现我们的数据库中的一些旧代码表现得并不像预期的那样.我设法将其缩小到条款的NULL价值效果IN.
我派生出一个测试来证明它:
declare @test nvarchar(50) = '8620M/9010';
declare @testLT nvarchar(50) = '8004/9010';
declare @testLV nvarchar(50) = null; --'asd'
select case when @test not in (@testLT, @testLV) then 1 else 0 end
Run Code Online (Sandbox Code Playgroud)
如果testLV为null,则NOT IN返回与IN子句相同的结果.
我想了解这种行为背后的机制.有人可以解释一下吗?
PS.我可能会用EXCEPT子句替换它
NOT IN通过NULL在列表中具有值来影响语义.在SQL中,NULL意思是"我不知道它的价值;它可能是任何东西."
所以,如果你这样做:
where 1 in (1, 2)
Run Code Online (Sandbox Code Playgroud)
然后它返回true.
where 1 in (3, 4)
Run Code Online (Sandbox Code Playgroud)
返回false.
到现在为止还挺好.现在考虑:
where 1 not in (1, 2, NULL)
Run Code Online (Sandbox Code Playgroud)
好吧,"1"显然在列表中.所以这会返回false.
where 1 not in (3, 4, NULL)
Run Code Online (Sandbox Code Playgroud)
好吧,"1"不是"3"或"4".但是NULL吗?我们不知道.所以,这会返回NULL而不是真实.并且NULL在WHERE条件中被视为与false相同,意味着该行被过滤掉.(作为一个注释: check条件表现不同,只有明确的假失败了check.)
因此,NOT IN如果有任何值,则不返回任何内容NULL.
这种情况几乎总是出现在子查询(而不是常量)的上下文中.出于这个原因,我建议使用NOT EXISTS而不是NOT IN在所有情况下使用子查询.
| 归档时间: |
|
| 查看次数: |
78 次 |
| 最近记录: |