NULL Значения в условии запроса - PullRequest
0 голосов
/ 11 октября 2018

Я пытаюсь сравнить нулевые значения, используя not in и существует, но я обнаружил некоторые различия. Почему последний запрос возвращает null?это связано с параметром БД?

--SET ANSI_NULLS On

CREATE TABLE #Tmp (id INT)
CREATE TABLE #Tmp1 (id INT)

INSERT INTO #Tmp(id) VALUES (1)
INSERT INTO #Tmp(id) VALUES (null)


INSERT INTO #Tmp1(id) VALUES (1)
INSERT INTO #Tmp1(id) VALUES (null)

SELECT id FROM #Tmp WHERE id IN (SELECT id FROM #tmp1)

SELECT id FROM #Tmp WHERE EXISTS(SELECT 1 FROM #Tmp1 WHERE #Tmp1.id = #Tmp.id)

SELECT id FROM #Tmp WHERE id NOT IN (SELECT id FROM #tmp1)

SELECT id FROM #Tmp WHERE NOT EXISTS(SELECT 1 FROM #Tmp1 WHERE #Tmp1.id = #Tmp.id)

DROP TABLE #Tmp
DROP TABLE #Tmp1 

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

В SQL Server помните, что NULL не возвращает проверку на равенство TRUE ни с чем (если вы не играете с ANSI_NULLS):

SELECT 1 
WHERE 1=NULL

SELECT 1
WHERE NULL = NULL

Возвращает True только тогда, когда вы используете IS / IS NOT

SELECT 1
WHERE NULL IS NULL

Для вашего последнего запроса единственной записью, удовлетворяющей этому требованию в предложении WHERE, является строка NULL.Эквивалент:

SELECT id FROM #Tmp 
WHERE id IS NULL

Чтобы решить вашу проблему, добавьте туда второе предложение:

SELECT id FROM #Tmp 
WHERE NOT EXISTS(
SELECT 1 
FROM #Tmp1 
WHERE #Tmp1.id = #Tmp.id OR #Tmp.id IS NULL
)
0 голосов
/ 11 октября 2018

Это очень просто:

id IN (1, NULL)
<=>
id = 1 OR id = NULL

И отрицание альтернативы :

id NOT IN (1, NULL)
<=>
id != 1 AND id != NULL -- yields NULL

Резюме:

Если выхотите использовать NOT IN, убедитесь, что ваш список не содержит NULL.

SELECT id FROM #Tmp WHERE id NOT IN (SELECT id FROM #tmp1 WHERE id IS NOT NULL)

SELECT id FROM #Tmp WHERE id NOT IN (SELECT COALESCE(id,-1) FROM #tmp1)
...