почему null не равно null false - PullRequest
       38

почему null не равно null false

21 голосов
/ 02 декабря 2009

Я читал эту статью: Получить ноль == ноль в SQL

И все согласны с тем, что при попытке проверить равенство между двумя (обнуляемыми) столбцами SQL, правильный подход:

where ((A=B) OR (A IS NULL AND B IS NULL))

Когда A и B равны NULL, (A = B) по-прежнему возвращает FALSE, поскольку NULL не равен NULL. Вот почему требуется дополнительная проверка.

А как насчет проверки неравенств? Исходя из вышеизложенного, я подумал, что для проверки неравенства мне нужно сделать что-то вроде:

WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))

Однако я заметил, что в этом нет необходимости (по крайней мере, в Inforix 11.5), и я могу просто сделать:

where (A<>B)

Если A и B равны NULL, это возвращает FALSE. Если NULL не равно NULL, то не должно ли это возвращать TRUE?

EDIT
Это все хорошие ответы, но я думаю, что мой вопрос был немного расплывчатым. Позвольте мне перефразировать:

Учитывая, что либо A, либо B могут быть NULL, достаточно ли проверить их неравенство с помощью

where (A<>B)

Или мне нужно явно проверить это так:

WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))

ОБРАТИТЕСЬ к этому ветке для ответа на этот вопрос.

Ответы [ 7 ]

34 голосов
/ 02 декабря 2009

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

Если вы думаете о NULL как о неизвестном, он становится намного более интуитивным:

unknown a равно unknown b? Там нет никакого способа узнать, поэтому: unknown.

26 голосов
/ 02 декабря 2009

реляционные выражения с участием NULL фактически возвращают NULL снова

редактировать

здесь, <> обозначает произвольный двоичный оператор, NULL - это заполнитель SQL, а value - любое значение (NULL равно , а не значение):

  • NULL <> value -> NULL
  • NULL <> NULL -> NULL

логика такова: NULL означает «нет значения» или «неизвестное значение», и поэтому любое сравнение с любым фактическим значением не имеет смысла.

равно X = 42 true, false или unknown, учитывая, что вы не знаете, какое значение (если any ) X имеет место? SQL говорит, что это неизвестно. X = Y верно, ложно или неизвестно, учитывая, что оба неизвестны? SQL говорит, что результат неизвестен . и так говорится для любой бинарной реляционной операции, которая является только логической (даже если наличие NULL в модели не на первом месте).

SQL также предоставляет два унарных постфиксных операторов, IS NULL и IS NOT NULL, которые возвращают TRUE или FALSE в соответствии с их операндом.

  • NULL IS NULL -> TRUE
  • NULL IS NOT NULL -> FALSE
7 голосов
/ 02 декабря 2009

Все сравнения с участием null не определены и оцениваются как ложные. Эта идея, которая предотвращает оценку null как эквивалентную null, также предотвращает оценку null как НЕ эквивалентную null.

4 голосов
/ 02 декабря 2009

Краткий ответ ... NULL странные , они не ведут себя так, как вы ожидаете.

Вот отличная статья о том, как NULL работают в SQL. Я думаю, что это поможет улучшить ваше понимание темы. Я думаю, что разделы по обработке нулевых значений в выражениях будут особенно полезны для вас.

http://www.oracle.com/technology/oramag/oracle/05-jul/o45sql.html

3 голосов
/ 02 декабря 2009

Нулевое поведение по умолчанию (ANSI) в выражении приведет к нулевому значению (в других случаях достаточно ответов).

Однако есть некоторые крайние случаи и предостережения, которые я бы сделал при работе с MS Sql Server, которых нет в списке.

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

В SQL Server можно переопределить логику выражения, касающуюся конкретного теста Null = Null, с помощью SET ANSI_NULLS OFF, который затем даст вам равенство между нулевыми значениями - это не рекомендуемый ход, но он существует. 1013 *

SET ANSI_NULLS OFF

select result =
    case
        when  null=null then 'eq' 
        else 'ne'
    end

SET ANSI_NULLS ON

select result =
    case
        when  null=null then 'eq' 
        else 'ne'
    end
2 голосов
/ 23 июня 2015

Вот быстрое исправление

ISNULL (А, 0) = ISNULL (В, 0)

0 можно изменить на то, чего никогда не произойдет в ваших данных

0 голосов
/ 03 декабря 2009

«Неизвестно, равно равно неизвестно б? Нет способа узнать, поэтому: неизвестно.»

Вопрос был: почему сравнение дает ЛОЖЬ?

Учитывая трехзначную логику, было бы разумно, чтобы сравнение приводило к НЕИЗВЕСТНОМУ (не ЛОЖНО). Но SQL дает FALSE, а не UNKNOWN.

Одна из множества извращений в языке SQL.

Кроме того, необходимо учитывать следующее:

Если в троичной логике "unkown" является логическим значением, то должно быть так, что сравнение на равенство между двумя логическими значениями, которые оба оказываются (значением) "unknown", тогда это сравнение должно дать TRUE.

Если логическое значение само по себе неизвестно, то, очевидно, это невозможно представить, поместив туда значение «неизвестно», поскольку это будет означать, что логическое значение известно (быть «неизвестно»). То есть, как реляционная теория доказывает, что реализация 3-значной логики повышает требование к 4-значной логике, что 4-значная логика приводит к необходимости 5-значной логики и т. Д. И т. Д. До бесконечности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...