Почему PostgreSQL не возвращает нулевые значения, когда условие <> true
Я был смущен за рассуждениями:
SELECT * FROM table WHERE avalue is null
Возвращает x число строк, где 'avalue' равно null
SELECT * FROM table WHERE avalue <> true
Возвращает строки не, где 'avalue' равно null.
Мое рассуждение (которое кажется неправильным) состоит в том, что как null
является уникальным значением (оно даже не равно null
) означает, что оно должно отображаться в результирующем наборе, поскольку оно не равно true
.
Я думаю, вы могли бы утверждать, что, сказав column <> value
, вы подразумеваете, что столбец имеет значение, поэтому игнорирует значения null
вообще.
Какова причина этого, и это то же самое в других общих SQL DB?
Мое рассуждение (предположение) говорит мне, что это противоречит интуиции, и я хотел узнать почему.
Ответы
Ответ 1
Каждая полупристойная РСУБД делает то же самое, потому что она правильная.
Я цитирую руководство Postgres здесь:
Обычные операторы сравнения дают null (обозначая "неизвестный" ), а не true или false, когда любой ввод равен NULL. Например, 7 = NULL
дает null, как и 7 <> NULL
. Если это поведение не подходит, используйте IS [ NOT ] DISTINCT FROM
:
expression IS DISTINCT FROM expression
expression IS NOT DISTINCT FROM expression
Обратите внимание, что эти выражения выполняют немного медленнее, чем просто сравнение expression <> expression
.
Для значений boolean
также существует более простая IS NOT [TRUE | FALSE]
.
Чтобы получить то, что вы ожидали в своем втором запросе, напишите:
SELECT * FROM table WHERE avalue IS NOT TRUE;
SQL Fiddle.
Ответ 2
Эта ссылка дает полезную информацию. Фактически, как указывает @Damien_The_Unbeliever, он использует трехзначную логику и, по-видимому, (в соответствии с этой статьей) является предметом дискуссий.
Несколько других хороших ссылок можно найти здесь и здесь.
Я думаю, что это сводится к null, не являющемуся значением, но владелец места для стоимости и решение должно быть принято, и это было... так что NULL не равно никому, потому что это не значение и даже не будет равно какой-либо величине.... если это имеет смысл.
Ответ 3
Это нормально. SQL Server делает это точно так же. В SQL Server вы можете использовать
SELECT * FROM table WHERE ISNULL(avalue, 0) <> 1
Для postgresql эквивалента смотрите это: Что такое эквивалент PostgreSQL для ISNULL()
Предположим использовать спецификацию NOT NULL со значением по умолчанию, если это имеет смысл.
EDIT:
Я думаю, что это логика. NULL не является значением, поэтому он исключается из поиска - вы должны указать его явно. Если разработчики SQL решают пойти вторым путем (включая нули автоматически), то вы получите больше проблем, если вам нужно распознать значения