Может кто-нибудь объяснить, пожалуйста, следующее поведение в 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)
Может кто-нибудь объяснить, пожалуйста, следующее поведение в 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)
Ответы:
<>
Стандарт SQL-92; !=
это его эквивалент. Оба оценивают значения, а NULL
не - NULL
это заполнитель, чтобы сказать, что значение отсутствует.
Вот почему вы можете использовать IS NULL
/ в IS NOT NULL
качестве предикатов только для таких ситуаций.
Это поведение не относится к SQL Server. Все совместимые со стандартами диалекты SQL работают одинаково.
Примечание . Для сравнения, если ваше значение не равно нулю , вы используете IS NOT NULL
, а для сравнения - не нулевое значение <> 'YOUR_VALUE'
. Я не могу сказать, равно или нет мое значение NULL, но я могу сказать, равно ли мое значение NULL или NOT NULL. Я могу сравнить, если мое значение отличается от NULL.
!=
до ~ 9i, как я понимаю, что привело к большому синтаксису ANSI-92. Я верю, что MySQL похож, начиная поддержку в 4.x.
!=
могло быть включено в более позднюю спецификацию в качестве альтернативы <>
. У меня нет новых спецификаций, поэтому я не могу сказать наверняка.
WHERE MyColumn != NULL
или WHERE MyColumn = NULL
детерминированным? Или, другими словами, гарантированно всегда возвращать 0 строк, независимо от того MyColumn
, обнуляется ли это в базе данных или нет?
!=
выполняется только оценка значений, выполнение чего-либо подобного WHERE MyColumn != 'somevalue'
не будет возвращать записи NULL.
NULL не имеет значения и поэтому не может сравниваться с использованием операторов скалярного значения.
Другими словами, никакое значение не может быть равно (или не равно) NULL, потому что NULL не имеет значения.
Следовательно, SQL имеет специальные предикаты IS NULL и IS NOT NULL для работы с NULL.
'a' != null
НЕ возвращать значение ( true
/ 1
) нелогично и время от времени меня ловит! Я бы подумал, что «какое-то значение по сравнению с отсутствием» всегда будет «не равным», но, может быть, это только я ?!
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
назначать константу, если она имеет значение NULL, при условии, что вы предоставляете соответствующий тип данных для значения дозорного x (в данном случае строка / символ). Это синтаксис TSQL, но Oracle и другие движки имеют схожие функции.
Обратите внимание, что это поведение является поведением по умолчанию (ANSI).
Если ты:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Вы получите разные результаты.
SET ANSI_NULLS OFF
видимо, уйду в будущем ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
установлено значение OFF, операторы сравнения Equals (=) и Not Equal To (<>) не соответствуют стандарту ISO. Оператор SELECT, который использует, WHERE column_name = NULL
возвращает строки с нулевыми значениями в column_name. Оператор SELECT, который использует, WHERE column_name <> NULL
возвращает строки, которые имеют ненулевые значения в столбце. Кроме того, оператор SELECT, который использует, WHERE column_name <> XYZ_value
возвращает все строки, которые не являются XYZ_value и которые не равны NULL. ИМХО, это последнее утверждение кажется немного странным в том смысле, что оно исключает нули из результатов!
В SQL все, что вы оцениваете / вычисляете с NULL
результатами в НЕИЗВЕСТНО
Вот почему SELECT * FROM MyTable WHERE MyColumn != NULL
или SELECT * FROM MyTable WHERE MyColumn <> NULL
дает вам 0 результатов.
Для проверки NULL
значений предусмотрена функция isNull.
Кроме того, вы можете использовать IS
оператор, как вы использовали в третьем запросе.
Надеюсь это поможет.
Единственный тест для NULL - это NULL или не NULL. Проверка на равенство бессмысленна, потому что по определению никто не знает, что это такое.
Вот статья в Википедии для чтения:
Мы используем
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
вернуть все строки, где MyColumn равен NULL, или все строки, где MyColumn является пустой строкой. Для многих «конечных пользователей» проблема пустых и пустых строк - это различие без необходимости и смысла.
Я просто не вижу функциональной и плавной причины, по которой значения NULL не сопоставимы с другими значениями или другими значениями NULL, поскольку мы можем четко сравнить их и сказать, что они одинаковы или нет в нашем контексте. Это забавно. Просто из-за некоторых логических выводов и последовательности мы должны постоянно с этим беспокоиться. Это не функционально, сделайте его более функциональным и предоставьте философам и ученым возможность сделать вывод, является ли оно последовательным или нет и содержит ли оно «универсальную логику». :) Кто-то может сказать, что это из-за индексов или чего-то еще, я сомневаюсь, что эти вещи не могут поддерживать нулевые значения, такие же как значения. Это то же самое, что сравнивать два пустых стакана, один - бокал для вина, а другой - бокал для пива, мы не сравниваем типы объектов, а значения, которые они содержат, так же, как вы могли бы сравнить int и varchar, с нулем it ' Еще проще, ничего общего и ничего общего с двумя небытиями, они одинаковы, очевидно сопоставимы мной и всеми, кто пишет sql, потому что мы постоянно нарушаем эту логику, сравнивая их странным образом из-за некоторых стандартов ANSI. Почему бы не использовать компьютерную мощность, чтобы сделать это для нас, и я сомневаюсь, что это замедлило бы ситуацию, если бы все, что связано, строилось с учетом этого. «Это не ноль, это ничего», это не яблоко, это apfel, давай ... Функционально это твой друг, и здесь тоже есть логика. В конце концов, единственное, что имеет значение, - это функциональность, и использование нулей таким образом приносит более или менее функциональность и простоту использования. Это более полезно? потому что мы постоянно нарушаем эту логику, сравнивая их странным образом из-за некоторых стандартов ANSI. Почему бы не использовать компьютерную мощность, чтобы сделать это для нас, и я сомневаюсь, что это замедлило бы ситуацию, если бы все, что связано, строилось с учетом этого. «Это не ноль, это ничего», это не яблоко, это apfel, давай ... Функционально это твой друг, и здесь тоже есть логика. В конце концов, единственное, что имеет значение, - это функциональность, и использование нулей таким образом приносит более или менее функциональность и простоту использования. Это более полезно? потому что мы постоянно нарушаем эту логику, сравнивая их странным образом из-за некоторых стандартов ANSI. Почему бы не использовать компьютерную мощность, чтобы сделать это для нас, и я сомневаюсь, что это замедлило бы ситуацию, если бы все, что связано, строилось с учетом этого. «Это не ноль, это ничего», это не яблоко, это apfel, давай ... Функционально это твой друг, и здесь тоже есть логика. В конце концов, единственное, что имеет значение, - это функциональность, и использование нулей таким образом приносит более или менее функциональность и простоту использования. Это более полезно? не яблоко, это apfel, давай ... Функционально это твой друг, и здесь тоже есть логика. В конце концов, единственное, что имеет значение, - это функциональность, и использование нулей таким образом приносит более или менее функциональность и простоту использования. Это более полезно? не яблоко, это apfel, давай ... Функционально это твой друг, и здесь тоже есть логика. В конце концов, единственное, что имеет значение, - это функциональность, и использование нулей таким образом приносит более или менее функциональность и простоту использования. Это более полезно?
Рассмотрим этот код:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Кто из вас знает, что вернет этот код? С или без НЕТ возвращает 0. Для меня это не функционально и сбивает с толку. В c # это все, как и должно быть, операции сравнения возвращают значение, логически это тоже создает значение, потому что если нет, сравнивать нечего (кроме. :)). Они просто «сказали»: все, что равно нулю, «возвращает» 0, и это создает много обходных путей и головных болей.
Это код, который привел меня сюда:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Мне просто нужно сравнить, если два поля (где) имеют разные значения, я мог бы использовать функцию, но ...
NULL Невозможно сравнить с любым значением с помощью операторов сравнения. NULL = NULL является ложным. Нуль не является значением. Оператор IS специально разработан для обработки пустых сравнений.
null = null
то, что можно использовать 1=0
в каком-то специальном запросе. И если они жалуются, я изменяю это на null != null
:)
Старый вопрос, но следующий может предложить более подробную информацию.
null
не представляет значение или неизвестное значение. В нем не указано, почему нет значения, что может привести к некоторой неопределенности.
Предположим, вы запустили такой запрос:
SELECT *
FROM orders
WHERE delivered=ordered;
то есть вы ищете строки, где ordered
и delivered
даты совпадают.
Чего ожидать, если один или оба столбца равны нулю?
Поскольку хотя бы одна из дат неизвестна, нельзя ожидать, что эти две даты совпадают. Это также тот случай, когда обе даты неизвестны: как они могут быть одинаковыми, если мы даже не знаем, какие они есть?
По этой причине любое выражение, рассматриваемое null
как значение, должно завершиться ошибкой. В этом случае он не будет совпадать. Это также имеет место, если вы попробуете следующее:
SELECT *
FROM orders
WHERE delivered<>ordered;
Опять же, как мы можем сказать, что два значения не одинаковы, если мы не знаем, что это такое.
SQL имеет специальный тест для пропущенных значений:
IS NULL
В частности, он не сравнивает значения, а скорее ищет пропущенные значения.
Наконец, что касается !=
оператора, насколько мне известно, его нет ни в одном из стандартов, но он очень широко поддерживается. Он был добавлен, чтобы программисты из некоторых языков чувствовали себя как дома. Честно говоря, если программисту трудно вспомнить, какой язык он использует, у него плохое начало.
NULL
мы имеем в виду, что мы сравниваем значение с «имеющим NULL
значение», а не с «неопределенным значением, которое есть в основе» NULL
, но что мы не знаем ", который, очевидно, мы не сможем когда-либо знать. Это действительно облегчило бы ситуацию.
IS NULL
гораздо сложнее, чем писать = NULL
. Я думаю, что было бы более последовательным, если бы WHERE columnA = columnB
имел такую же интерпретацию WHERE columnA = NULL
, а не рассматривать последний как особый случай. Помните, что NULL
это не ценность. В языках программирования , где он является законным , чтобы проверить variable == null
это , потому что null
имеет другое значение; это не представляет что-то неизвестное, но преднамеренное восстановление значения. Не так с SQL.
IS NULL
AND =NULL
. Но взгляните на последний Ховер. Я устал испытывать это снова и снова, делая ненужные нагрузки? дополнительная проверка ...
Я хотел бы предложить этот код, который я сделал, чтобы найти, есть ли изменение в значении,
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 делает его совместимым для различных типов
NULL это не что-нибудь ... это неизвестно. NULL не равняется ничему. Вот почему вы должны использовать волшебную фразу IS NULL вместо = NULL в ваших SQL-запросах.
Вы можете сослаться на это: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
что это в спецификации 92, но большинство поставщиков поддерживают!=
и / или она включена в более позднюю спецификацию, такую как 99 или 03.