我正在寻找以下三个查询中的一个为什么没有返回我期望的解释。
-- Query 1
SELECT ANNo, ANCpr
FROM Anmodning
WHERE LEFT(ANCpr,6) + '-' + RIGHT(ANCpr,4) NOT IN (SELECT PSCpr FROM Person)
-- Query 2
SELECT ANNo, ANCpr
FROM Anmodning a
LEFT JOIN Person p ON p.PSCpr = LEFT(a.ANCpr,6) + '-' + RIGHT(a.ANCpr,4)
WHERE p.PSNo IS NULL
-- Query 3
SELECT ANNo, ANCpr
FROM Anmodning
WHERE ANNo NOT IN
(
SELECT ANNo
FROM Anmodning
WHERE LEFT(ANCpr,6) + '-' + RIGHT(ANCpr,4) IN (SELECT PSCpr FROM Person)
)
假设以下内容:
使用ANNo = 1进行修改,ANCpr = 1111112222
而且Person表没有没有一行,其PSCpr = 111111-2222
查询是在Management Studio中针对SQL Server 2017执行的。
查询2和3按预期返回Anmodning行,但查询1不返回。 为什么呢?
答案 0 :(得分:0)
我怀疑第一个查询的问题是null-safety问题。如果Person(PSCpr)
中存在空值,则not in
条件将滤除所有Anmodning
行,而与Person
中的其他值无关。
考虑以下简单示例:
select 1 where 1 not in (select 2 union all select null)
不返回任何行,而:
select 1 where 1 not in (select 2 union all select 3)
返回您期望的1
。
与第二个查询一样,使用left join
时不会发生此问题。
您还可以使用not exists
是安全的null
来表达这一点,我会在这里推荐
SELECT ANNo, ANCpr
FROM Anmodning a
WHERE NOT EXITS (SELECT 1 FROM Person p WHERE p.PSCpr = LEFT(a.ANCpr,6) + '-' + RIGHT(a.ANCpr,4))