IS NULL по сравнению с <> 1 бит SQL
У меня есть столбец бит в таблице в базе данных SQL Server 2012.
Я пытаюсь получить все строки, где этот столбец бит имеет значение NULL
или NOT TRUE.
Этот запрос не возвращает то, что ему нужно: (возвращает 0 строк)
Select *
from table
where bit_column_value <> 1
Этот запрос возвращает правильные строки:
Select *
from table
where bit_column_value IS NULL
Теперь я был бы рад использовать второй запрос, но моя проблема в том, что в аналогичном запросе для другой таблицы обратное из вышеизложенного верно, где работает первый способ, но второй способ не!
Помог ли кто-нибудь объяснить, в чем разница в приведенном выше? Я специально обновил соответствующие столбцы бит как NULL, и это не изменит результаты. (Возможно, была разница между значениями "Пусто" и NULL
.
Заранее благодарим за любые объяснения.
Ответы
Ответ 1
Причина <>
не работает, так как SQL рассматривает NULL
как неизвестный - он не знает, что означает NULL
, поэтому он оценивает как =
, так и <>
на NULL
значение UNKNOWN
(которое рассматривается как ложное в условии where или условии соединения). Для получения дополнительной информации прочтите следующее: Почему NULL = NULL оценивает значение false на сервере SQL.
Если индекс на нем, используя функцию ISNULL, будет означать, что индекс не может использоваться, поэтому
убедитесь, что запрос может использовать индекс, просто используйте OR
:
SELECT *
FROM TableName
WHERE
bit_column_value IS NULL OR bit_column_value = 0
Ответ 2
лучше всего написать запрос как таковой:
SELECT
*
FROM
table
WHERE
ISNULL(bit_column_value, 0) = 0
Это должно возвращать все записи NULL и FALSE.
Не видя структуру и данные таблицы, я не могу прокомментировать, почему вы получаете разные результаты от двух запросов.
Ответ 3
MSDN говорит, что тип BIT может хранить значения 0, 1 или NULL. (Тот факт, что значение BIT равно NULL, должно храниться отдельно от самого значения бита, так как битовые значения могут быть сжаты, так что 8 значений BIT сохраняются в байте.)
Помните, что условие в предложении WHERE выбирает строку, когда условие TRUE. Для большинства бинарных предикатов (условий), если вы сравниваете NULL с некоторым значением, результат будет NULL или UNKNOWN (не TRUE). Так, например, если значение в столбце равно NULL, то column = 0
оценивается как NULL или UNKNOWN, а также column <> 0
.
Глядя на ваши запросы:
SELECT * FROM table WHERE bit_column_value <> 1
Если значение в столбце bit_column_value
равно 1, условие равно FALSE, поэтому строка не возвращается; где значение равно 0, условие TRUE, поэтому строка возвращается; и где значение NULL, условие также равно NULL или UNKNOWN, поэтому строка не возвращается.
SELECT * FROM table WHERE bit_column_value IS NULL
В соответствии со стандартом SQL предикат IS [NOT] NULL и предикаты IS [NOT] {TRUE | FALSE | UNKNOWN} несколько отличаются. Тест IS NULL возвращает TRUE, если тестируемое значение равно NULL; в противном случае они возвращают FALSE (и никогда не возвращаются UNKNOWN). Тесты IS [NOT] {TRUE | FALSE | UNKNOWN} аналогичны; они возвращают TRUE, если значение имеет указанный тип и FALSE в противном случае (не UNKNOWN). Например:
Column IS TRUE IS FALSE IS UNKNOWN IS NOT TRUE IS NOT FALSE IS NOT UNKNOWN
FALSE FALSE TRUE FALSE TRUE FALSE TRUE
TRUE TRUE FALSE FALSE FALSE TRUE TRUE
NULL FALSE FALSE TRUE TRUE TRUE FALSE
Итак, во втором запросе будут выбраны только те строки, где значение bit_column_value
равно NULL (которое отделено от 0 и 1), а не TRUE, а также FALSE.
Я пытаюсь получить все строки, в которых этот столбец бит имеет значение NULL или NOT TRUE.
Попробуйте написать запрос непосредственно из вашей спецификации:
-
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value IS NOT TRUE
-
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value = FALSE
-
SELECT * FROM table WHERE bit_column_value IS NULL OR bit_column_value <> TRUE
-
SELECT * FROM table WHERE bit_column_value IS NOT TRUE
Учитывая приведенную выше таблицу истинности, запрос 4 даст результат, который вы хотите - с большой оговоркой, что я не уверен, что MS SQL Server поддерживает IS [NOT] {TRUE | FALSE | UNKNOWN}. Судя по MSDN на Predicates, предикаты IS [NOT] {TRUE | FALSE | UNKNOWN} не поддерживаются (но я, возможно, пропустил правильную часть руководства). Если это правильно, вам нужно использовать один из запросов 2 или 3.
(Есть несколько дополнительных осложнений с этими предикатами, когда значение не является простым столбцом, но является значением строки. Однако это не имеет отношения к вашему вопросу или проблеме, а не потому, что MS SQL Server, похоже, не поддерживает их. )
Ответ 4
Пожалуйста, проверьте данные таблицы, если она содержит value = 0?
Тип данных SQL Бит может иметь только значение 0, 1 или NULL
, если вы вставляете другое значение, оно считается равным 1 ( Исключение: если вы введете 'False
', оно станет 0, 'True
' станет 1).
Например:
insert into t1 values (1),(2),(1),(3),(-1),(0),(NULL),('false'),('true')
Результат:
1, 1, 1, 1, 1, 0, NULL, 0, 1
Ответ 5
Я думаю, это связано с тем, что все данные имеют значения NULL
в этом столбце. Итак:
Select *
from table
where bit_column_value <> 1;
Не даст вам результат. Поскольку NULL
неизвестно. И это:
Select *
from table
where bit_column_value IS NULL;
Дает вам результат, который вы ищете.
Но у вас есть неправильное представление о представлении true и false с использованием типа данных bit
.
Вы представляете false как NULL
, 0
пусто, а true - любое другое значение. Типы данных bit
работают как @IswantoSan, объясненные в его ответе; Он должен быть 0 или 1 или NULL
:
- 0 false,
- 1 истинно,
-
NULL
пусто.
Поэтому, чтобы получить:
-
true
значения используют where bit_column_value = 1
.
-
false
значения используют where bit_column_value = 0
.
-
NULL
или пустой where bit_column_value IS NULL
.
-
NULL or not true:
где bit_column_value IS NULL или бит_column_value = 0`.
Другое дело отметить, что NULL
и пустые две разные вещи, они не совпадают. В случае bit
тип данных пустой - NULL
не 0, так как 0 должен быть ложным. Но рассмотрим строковый тип данных, например VARCHAR
, то пустая строка ''
полностью отличается от значения NULL
.