Не равны != оператор на NULL

может кто-нибудь объяснить следующее поведение в SQL?

SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)

11 ответов


<> является стандартным SQL-92;!= является его эквивалентом. Оба оценивают значения, которые NULL не -- NULL является заполнителем, чтобы сказать, что существует отсутствие значения.

вот почему вы можете использовать только IS NULL/IS NOT NULL как предикаты для таких ситуаций.

это поведение не относится к SQL Server. Все диалекты SQL, совместимые со стандартами, работают одинаково.

Примечание: Для сравнения, если ваш значение не значение null, вы используете IS NOT NULL, а сравнивать с не null значение, вы используете <> 'YOUR_VALUE'. Я не могу сказать, равно или не равно мое значение NULL, но я могу сказать, является ли мое значение NULL или NOT NULL. Я могу сравнить, если мое значение что-то другое, чем NULL.


NULL не имеет значения, и поэтому его нельзя сравнить с помощью скалярных операторов значений.

другими словами, никакое значение не может быть равно (или не равно) NULL, потому что NULL не имеет значения.

следовательно, SQL имеет специальные значения NULL и не является нулевыми предикатами для работы с NULL.


обратите внимание, что это поведение является поведением по умолчанию (ANSI).

Если вы:

 SET ANSI_NULLS OFF

http://msdn.microsoft.com/en-us/library/ms188048.aspx

вы получите разные результаты.

SET ANSI_NULLS OFF по-видимому, будет уходить в будущем...


в SQL все, что вы оцениваете / вычисляете с помощью NULL результаты в неизвестном

вот почему SELECT * FROM MyTable WHERE MyColumn != NULL или SELECT * FROM MyTable WHERE MyColumn <> NULL дает 0 результатов.

предоставить чек на NULL значения, функция isNull предоставляется.

кроме того, вы можете использовать IS оператор, как вы использовали в третьем запросе.

надеюсь, что это помогает.


единственным тестом для NULL является NULL или не является NULL. Тестирование на равенство бессмысленно, потому что по определению никто не знает, что такое значение.

вот статья Википедии, чтобы прочитать:

https://en.wikipedia.org/wiki/Null_ (SQL)


мы используем:

SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';

чтобы вернуть все строки, в которых столбец mycolumn компонент компонент имеет значение null или все строки, в которых столбец mycolumn компонент компонент является пустой строкой. Для многих "конечного пользователя", значение null и пустые строки проблема-это различие без необходимости и степени смешения.


NULL нельзя сравнить с любым значением с помощью операторов сравнения. NULL = NULL равно false. Null не является значением. Оператор IS специально разработан для обработки нулевых сравнений.


Я просто не вижу функциональной и бесшовной причины, по которой нули не сопоставимы с другими значениями или другими нулями, потому что мы можем четко сравнить его и сказать, что они одинаковы или нет в нашем контексте. Забавно. Просто из-за некоторых логических выводов и последовательности нам нужно постоянно беспокоиться об этом. Это не функционально, сделайте его более функциональным и предоставьте философам и ученым делать вывод, является ли он последовательным или нет и имеет ли он "универсальную логику". :) Кто-то может сказать что это из-за индексов или чего-то еще, я сомневаюсь, что эти вещи не могут быть сделаны для поддержки нулей, таких же, как значения. Это тоже самое, что сравнивать два пустых стакана, одна Лоза, стекло и другой пивной бокал, мы не сравниваем типы объектов, а значения, которые они содержат, так же, как вы могли бы сравнить int и varchar, с нулем еще проще, ничего и то, что две небытие есть общее, они же, явно сопоставимы по мне и всем остальным, что писать SQL, потому что мы постоянно нарушая эту логику, сравнивая их странными способами из-за некоторых стандартов ANSI. Почему бы не использовать компьютерную энергию, чтобы сделать это за нас, и я сомневаюсь,что это замедлит процесс, если все, что связано, будет построено с учетом этого. "Это не null, это ничего", это не apple, это apfel, давай... Функционально это ваш друг, и здесь также есть логика. В конце концов, единственное, что имеет значение, - это функциональность и использование нулей таким образом приносит больше или меньше функциональности и простоты использования. Это более полезным?

рассмотрим этот код:

SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end

сколько из вас знает, что этот код возврата? С или без не он возвращает 0. Для меня это не функционально и сбивает с толку. В c# все так, как должно быть, операции сравнения возвращают значение, логически это тоже производит значение, потому что, если это не так, сравнивать нечего (кроме. ничего.) ): Они просто "сказали": что-нибудь по сравнению с null "возвращает" 0, и это создает много обходных путей и головная боль.

это код, который привел меня сюда:

where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)

мне просто нужно сравнить, если два поля (где) имеют разные значения, я мог бы использовать функцию, но...


старый вопрос, но может предложить более подробно.

null не представляет значения или неизвестного значения. Он не указывает почему нет значения, которое может привести к некоторой двусмысленности.

Предположим, вы выполняете такой запрос:

SELECT *
FROM orders
WHERE delivered=ordered;

то есть, вы ищете строки, где ordered и delivered даты те же.

что следует ожидать, когда один или оба столбца имеют значение null?

потому что по крайней мере одна из дат неизвестна, вы не можете ожидать, чтобы сказать, что 2 даты совпадают. Это также имеет место, когда и даты неизвестны: как они могут быть одинаковыми, если мы даже не знаем, какие они?

по этой причине, любое выражение лечении null как значение должно завершиться ошибкой. В этом случае он не будет соответствовать. Это также имеет место, если вы попробуете следующее:

SELECT *
FROM orders
WHERE delivered<>ordered;

снова, как мы можем сказать, что два значения не то же самое, если мы не знаем, что это такое.

SQL имеет определенный тест для отсутствующих значений:

IS NULL

конкретно это не сравнение значения, но скорее он ищет отсутствует значения.

наконец, что касается != оператор, насколько мне известно, на самом деле он не входит ни в один из стандартов, но он очень широко поддерживается. Он был добавлен, чтобы программисты с некоторых языков чувствовали себя как дома. Честно говоря, если программист имеет трудно вспомнить, на каком языке они говорят, у них плохое начало.


NULL-это не что-то ... это неизвестно. NULL ничего не значит. Вот почему вы должны использовать волшебную фразу is NULL вместо = NULL в ваших SQL-запросах

вы можете сослаться на это:http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx


Я хотел бы предложить этот код, который я сделал, чтобы найти, есть ли изменение в значении, i быть новым значением и d будучи старым (хотя порядок не имеет значения). Если на то пошло, изменение от value к null или наоборот является изменением, но от null к null не является (конечно, от value к другому значению является изменением, но от value к тому же это не так).

CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
    @i sql_variant,
    @d sql_variant
)
RETURNS bit
AS
BEGIN
    DECLARE @in bit = 0, @dn bit = 0
    if @i is null set @in = 1
    if @d is null set @dn = 1

    if @in <> @dn
        return 0

    if @in = 1 and @dn = 1
        return 1

    if @in = 0 and @dn = 0 and @i = @d
        return 1

    return 0

END

чтобы использовать эту функцию, вы можете

declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)

---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp

---- where equal ----
select *,'equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 1

---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where  [dbo].[ufn_equal_with_nulls](a,b) = 0

результаты являются:

---- in select ----
a   b   =
1   1   1
1   2   0
1   NULL    0
NULL    1   0
NULL    NULL    1

---- where equal ----
1   1   equal
NULL    NULL    equal

---- where not equal ----
1   2   not equal
1   NULL    not equal
NULL    1   not equal

использование sql_variant делает его совместимым для различных типов