Может кто-нибудь объяснить следующее поведение 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.
NULL не имеет значения и поэтому не может сравниваться с использованием операторов скалярного значения.
Другими словами, ни одно значение не может быть равно (или не равно) NULL, потому что NULL не имеет значения.
Следовательно, SQL имеет специальные IS NULL и IS NOT NULL предикаты для работы с NULL.
Обратите внимание, что это поведение по умолчанию (ANSI).
Если вы:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
Вы получите разные результаты.
SET ANSI_NULLS OFF
, очевидно, исчезнет в будущем...
Единственный тест для NULL - это NULL или NOT NULL. Тестирование на равенство бессмысленно, потому что по определению никто не знает, что такое значение.
Вот статья в Википедии:
В SQL все, что вы оцениваете/вычисляете с помощью результатов NULL
в UNKNOWN
Вот почему SELECT * FROM MyTable WHERE MyColumn != NULL
или SELECT * FROM MyTable WHERE MyColumn <> NULL
дает вам 0 результатов.
Чтобы обеспечить проверку значений NULL
, предоставляется функция isNull.
Кроме того, вы можете использовать оператор IS
, как вы использовали в третьем запросе.
Надеюсь, что это поможет.
Мы используем
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
чтобы вернуть все строки, где MyColumn равен NULL, или все строки, где MyColumn - пустая строка. Для многих "конечных пользователей" проблема с NULL и пустой строкой является различием без необходимости и путаницы.
NULL Нельзя сравнивать с каким-либо значением с помощью операторов сравнения. NULL = NULL является ложным. Нуль - это не значение. Оператор IS специально разработан для сравнения NULL.
Я просто не вижу, чтобы функциональная и цельная причина того, что нули не были сопоставимы с другими значениями или другими значениями нуля, потому что мы можем четко сравнить их и сказать, что они такие же или нет в нашем контексте. Это смешно. Просто из-за некоторых логических выводов и последовательности мы должны постоянно беспокоиться об этом. Это не является функциональным, делает его более функциональным и оставляет его философам и ученым, если они согласуются или нет и придерживаются "универсальной логики".:) Кто-то может сказать, что это из-за индексов или чего-то еще, я сомневаюсь, что эти вещи не могут быть использованы для поддержки нулей, таких же, как значения. Это то же самое, что сравнение двух пустых стаканов, один из них - виноградное стекло, а другое - это пивное стекло, мы не сравниваем типы объектов, но значения, которые они содержат, так же, как вы могли бы сравнить int и varchar, с нулевым, это еще проще, это ничего и что два ничего не имеют общего, они одинаковы, четко сопоставимы мной и всеми остальными, которые пишут sql, потому что мы постоянно нарушаем эту логику, сравнивая их странными способами из-за некоторых стандартов ANSI. Почему бы не использовать компьютерную мощь, чтобы сделать это для нас, и я сомневаюсь, что это замедлит работу, если все, что связано, будет построено с учетом этого. "Это не нуль, это ничего", это не яблоко, это апфель, давай... Функционально ваш друг, и здесь есть логика. В конце концов, единственное, что имеет значение, - это функциональность, и использование нулей таким образом обеспечивает более или менее функциональность и простоту использования. Это более полезно?
Рассмотрим этот код:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Сколько из вас знает, что вернет этот код? С или без НЕ возвращает 0. Мне это не работает, и это сбивает с толку. В С# все как и должно быть, операции сравнения возвращают значение, логически это тоже приводит к значению, потому что, если это не так, сравнивать нечего (кроме. Ничего:)). Они просто "сказали": все по сравнению с нулевыми "возвращает" 0, и это создает много обходных решений и головных болей.
Это код, который привел меня сюда:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Мне просто нужно сравнить, если два поля (где) имеют разные значения, я мог бы использовать функцию, но...
Старый вопрос, но следующее может предложить более подробную информацию.
null
не имеет значения или неизвестного значения. Он не указывает, почему нет никакой ценности, что может привести к некоторой двусмысленности.
Предположим, вы запустили такой запрос:
SELECT *
FROM orders
WHERE delivered=ordered;
то есть вы ищете строки, где ordered
и delivered
даты одинаковы.
Что можно ожидать, когда один или оба столбца являются нулевыми?
Поскольку хотя бы одна из дат неизвестна, вы не можете ожидать, что две даты совпадают. Это также случай, когда обе даты неизвестны: как они могут быть одинаковыми, если мы даже не знаем, что это такое?
По этой причине любое выражение, обрабатывающее null
как значение, должно терпеть неудачу. В этом случае он не будет соответствовать. Это также происходит, если вы попробуете следующее:
SELECT *
FROM orders
WHERE delivered<>ordered;
Опять же, как мы можем сказать, что два значения не совпадают, если мы не знаем, что они собой представляют.
SQL имеет специальный тест на отсутствие значений:
IS NULL
В частности, он не сравнивает значения, а ищет недостающие значения.
Наконец, что касается оператора !=
, Насколько мне известно, на самом деле он ни в одном из стандартов не поддерживается, но он очень широко поддерживается. Он был добавлен, чтобы заставить программистов с некоторых языков чувствовать себя как дома. Честно говоря, если программист с трудом запоминает, какой язык они используют, они начинают плохо работать.
NULL - это не что-то... это неизвестно. NULL ничего не значит. Вот почему вы должны использовать магическую фразу IS NULL вместо = NULL в ваших SQL-запросах
Вы можете сослаться на это: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
Я хотел бы предложить этот код, который я сделал, чтобы найти, есть ли изменение значения,
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 делает его совместимым для различных типов