Skip to content
Advertisement

Query not returning expected data

I’m looking for an explanation for why 1 of the following 3 queries aren’t returning what I am expecting.

-- 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)
)

Assume the following:
Anmodning with ANNo=1, ANCpr=1111112222
And the Person table doesn’t have a row with PSCpr=111111-2222
Queries are executed in Management Studio against a SQL Server 2017.

Queries 2 and 3 returns the Anmodning row as expected but query 1 does not. Why is that?

Advertisement

Answer

I suspect the issue with the first query is a null-safety problem. If there are null values in Person(PSCpr), then the not in condition filters out all Anmodning rows, regardless of other values in Person.

Consider this simple example:

select 1 where 1 not in (select 2 union all select null)

Returns no rows, while:

select 1 where 1 not in (select 2 union all select 3)

Returns 1 as you would expect.

This problem does not happen when you use left join, as in the second query.

You could also phrase this with not exists, which is null-safe, which I would recommend here:

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))
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement