5

В SQL фигурирует значение NULL, функциональная роль которого заключается в обозначении отсутствующих или неизвестных данных. Для этого значения установлены правила выполнения предикатов, которые при участии NULL возвращают не TRUE или FALSE, а UNKNOWN, что вполне соответствует бытовой логике: если одно из данных отсутствует, то результат операции нам неизвестен. Но есть ли у такого расширения до троичной логики функциональная роль, или на практике, если заменить все UNKNOW на FALSE, то мы не заметим разницы? Насколько я знаю, от предиката требуется вернуть TRUE, чтобы произошло некоторое действие. Быть может, в разных реализациях это устроенно по разному? Буду рад каким-нибудь рассказам или ссылкам на эту тему.

Viktorov
  • 7,195
  • 10
  • 37
  • 66

2 Answers2

2

Если заменить Unknown значения на False, то возникают неоднозначности:

  • Not False = True, но Not Unknown != True.

  • Из предыдущего следует False or Not False = True. Но Unknown or Not Unknown != True. Не всегда любое высказывание либо истинно, либо ложно.

Например:

Выведем продукты, которые стоят больше не больше 100:

select * from products t1 where not t1.price>100

В этом вариант в результат не попадут строки, в которых стоимость(price) не известна. Если же Unknown заменить на False, то в результат попали бы строчки, для которых стоимость не известна, что не соответствует истине.

PS

Справедливости ради надо сказать, что в данном примере запрос можно переписать для правильной работы в случае FALSE = Unknown

select * from products t1 where t1.price<=100
Viktorov
  • 7,195
  • 10
  • 37
  • 66
  • Все-таки Unknown, а не Null. И в SQL логические значения нельзя сравнивать. – Pavel Mayorov Jul 20 '17 at 12:53
  • @IDrakonl, спасибо за ответ. По поводу ответа: заменять на FALSE предлагается не NULL (что невозможно хотя бы по причинам типа данных), а UNKNOW как результат выполнения предиката. Непонятно что означает предложение заменить в price NULL на FALSE, это же real.

    То есть вопрос не о разнице между троичной и двоичной логиками, а о функциональном значении троичной логики в SQL.

    – Akari Gale Jul 20 '17 at 12:56
  • @PavelMayorov в случае Oracle sql UNKNOW и NULL - это одно и то же. Про сравнение справедливо. Я плохо выразил свои мысли, сейчас исправлю – Viktorov Jul 20 '17 at 13:05
  • @lDrakonl Но ANSI SQL их различает, а на вопросе стоит общая метка. – Pavel Mayorov Jul 20 '17 at 13:06
  • @PavelMayorov а в рамках этого вопроса есть какая то разница в действительности? Я могу заменить null на unknown в нужных местах, если для этого существует объективная причина – Viktorov Jul 20 '17 at 13:08
  • @lDrakonl, Ваши примеры просто не отвечают на поставленный вопрос. Правильно они выглядят так: X = X - это TRUE, NULL = NULL - это UNKNOWN, но никакого изменения функциональной структуры от замены этого UNKNOWN на FALSE Ваш пример не высвечивает. – Akari Gale Jul 20 '17 at 13:14
  • @AkariGale кажется я изначально не совсем понял вопрос. Но разве часть про отрицание не отвечает на него? NOT UNKNOWN!=TRUE, а NOT FALSE=TRUE – Viktorov Jul 20 '17 at 13:23
  • Понятно, что если изменить UNKNOW на FALSE, то логика станет беднее, а некоторые истинные соотношения перейдут в ложные. Но что будет, если заменить конкретно в SQL все UNKNOWN на FALSE. Например считать, что NULL > 0 -> FALSE.

    Ваш пример про замену касался price, но я говорю не о первичных данных, а о результатах выполнения предикатов.

    – Akari Gale Jul 20 '17 at 13:26
  • Что подразумевается под словами "в результатах выполнения предикатов" ? price > 100 - это и есть предикат. И not price >100 это тоже предикат. В общем я тогда не понимаю Ваш вопрос =( – Viktorov Jul 20 '17 at 13:29
  • @lDrakonl, прошу прощения, теперь я невнимательно прочел Ваш пример, из-за того что в начале UNKNOWN обозначался как NULL. Да, я уловил разницу, спасибо. – Akari Gale Jul 20 '17 at 13:37
  • @AkariGale на самом деле мне не понятна причина добавления UNKNOWN. В троичной логике 3 значения - true, false, null. Предикаты на этих значениях возвращают в результате одно из этих же значений. Похоже на то, что unknown вводится просто для удобства – Viktorov Jul 20 '17 at 13:52
2

При выборке данных необходимо, чтобы предикат был TRUE.

При вставке данных в таблицу предикат не должен быть FALSE (т.е. TRUE или UNKNOWN).

Viktorov
  • 7,195
  • 10
  • 37
  • 66