Не равен <>!= Оператор в 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)

Ответ 1

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

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

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

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

Ответ 2

NULL не имеет значения и поэтому не может сравниваться с использованием операторов скалярного значения.

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

Следовательно, SQL имеет специальные IS NULL и IS NOT NULL предикаты для работы с NULL.

Ответ 3

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

Если вы:

 SET ANSI_NULLS OFF

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

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

SET ANSI_NULLS OFF, очевидно, исчезнет в будущем...

Ответ 4

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

Вот статья в Википедии:

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

Ответ 5

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

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

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

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

Надеюсь, что это поможет.

Ответ 6

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

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

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

Ответ 7

NULL Нельзя сравнивать с каким-либо значением с помощью операторов сравнения. NULL = NULL является ложным. Нуль - это не значение. Оператор IS специально разработан для сравнения NULL.

Ответ 8

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

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

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

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

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

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

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

Ответ 9

Старый вопрос, но следующее может предложить более подробную информацию.

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

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

SELECT *
FROM orders
WHERE delivered=ordered;

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

Что можно ожидать, когда один или оба столбца являются нулевыми?

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

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

SELECT *
FROM orders
WHERE delivered<>ordered;

Опять же, как мы можем сказать, что два значения не совпадают, если мы не знаем, что они собой представляют.

SQL имеет специальный тест на отсутствие значений:

IS NULL

В частности, он не сравнивает значения, а ищет недостающие значения.

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

Ответ 10

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

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

Ответ 11

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

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 делает его совместимым для различных типов