Необычный результат запроса сервера sql

Скажем, у меня есть таблица под названием nameAge:

ID  Name  Age
1   X     12
2   Y     12
3   null  null
4   Z     12

и когда я запускаю запрос вроде:

select * from nameAge where Age <> 12

он возвращает мне пустой набор результатов, когда у меня есть строка с id 3, где age отличается от null?

Используя Sql Server 2008 R2.

Любые идеи?

Изменить: возможность дублирования с предлагаемым ответом может быть в какой-то момент, но не распространяется вообще, и она показывает, как использовать пустые значения по сравнению с нулем, но то, что я хотел спросить, было о наборе результатов, который включает в себя нулевые значения

Ответ 1

Это предполагаемое поведение. Вы не можете сравнить значения NULL с помощью = или <>. Вы должны использовать IS NULL или IS NOT NULL.

Если вы хотите, чтобы значения NULL использовали только IS NULL:

select * from nameAge where age IS NULL

Если вы хотите NULL значения с age <> 12 значениями, используйте:

select * from nameAge where age <> 12 OR age IS NULL

Ответ 2

Выражение

WHERE NULL <> 12

не возвращает TRUE или FALSE, но на самом деле возвращает UNKNOWN. Это означает, что третья запись в вашей таблице не будет возвращена вашим запросом.

Как упоминалось в @ughai, вы должны использовать IS NULL вместо этого для запроса этой записи:

SELECT * FROM nameAge WHERE age IS NULL

За дополнительной информацией обратитесь к документации Microsoft SQL Server.

Ответ 3

Когда вы имеете дело с NULLs, вы всегда должны быть осторожны из-за 3-значной логики, используемой в Sql Server (когда предикат можно оценить с помощью TRUE, FALSE или UNKNOWN). Теперь вот классический оператор select, в котором многие новички совершают ошибку, предполагая, что оператор вернет все строки, где Age <> 12 включая NULLs.

Но если вы знаете легкий факт, что при сравнении NULL с любым значением даже сам NULL будет оцениваться до UNKNOWN, становится понятнее, что происходит. WHERE возвращает ТОЛЬКО те строки, где предикат оценивается как TRUE. Строки, где предикат оценивается как FALSE или UNKNOWN, будут отфильтрованы из набора результатов.

Теперь посмотрим, что происходит за сценой. У вас есть 4 строки:

ID    Name    Age
1     X       12
2     Y       12
3     null    null
4     Z       12

и предикат:

where Age <> 12

Когда вы оцениваете этот предикат для каждой строки, вы получаете:

ID    Name    Age   Evaluation result
1     X       12    FALSE              --(because 12 <> 12 is FALSE)
2     Y       12    FALSE              --(because 12 <> 12 is FALSE)
3     null    null  UNKNOWN            --(because NULL <> 12 is UNKNOWN)
4     Z       12    FALSE              --(because 12 <> 12 is FALSE)

Теперь помните, что предложение WHERE будет возвращать только строки, где предикат оценивается как TRUE, и ясно, что вы не получите никакого результата, потому что ни одна строка не оценивает TRUE.