Sql 未知:如果我们甚至不知道它们是什么,它们怎么可能是一样的
因此,任何将Sql 未知:如果我们甚至不知道它们是什么,它们怎么可能是一样的,sql,sql-server,tsql,null,Sql,Sql Server,Tsql,Null,因此,任何将null视为值的表达式都必须失败。在这种情况下,它将不匹配。如果您尝试以下操作,也会出现这种情况: SELECT * FROM orders WHERE delivered<>ordered; 具体来说,它不是比较值,而是寻找缺失的值 最后,关于=operator,据我所知,它实际上不在任何标准中,但它得到了非常广泛的支持。添加它是为了让来自某些语言的程序员感到更自在。坦率地说,如果程序员记不起他们使用的是什么语言,那么他们就有了一个糟糕的开始。+1。而且,与OP声明相
null
视为值的表达式都必须失败。在这种情况下,它将不匹配。如果您尝试以下操作,也会出现这种情况:
SELECT *
FROM orders
WHERE delivered<>ordered;
具体来说,它不是比较值,而是寻找缺失的值
最后,关于
=
operator,据我所知,它实际上不在任何标准中,但它得到了非常广泛的支持。添加它是为了让来自某些语言的程序员感到更自在。坦率地说,如果程序员记不起他们使用的是什么语言,那么他们就有了一个糟糕的开始。+1。而且,与OP声明相反,这不是“Microsoft SQL”。三元逻辑是在SQL标准中定义的,MS在这一点上遵循标准。我并不是说这只是微软的行为。我只是说我在Microsoft SQL Server上观察到了它。出于兴趣,是否存在这种(预期的)行为有用的情况?在我看来,似乎有了'a'!=null不返回值(true
/1
)是违反直觉的,有时会让我抓狂!我本以为“有些价值与没有价值相比”永远是“不相等的”,但也许那只是我?!?我认为有意思的是,人们把NULL描述为“没有价值”。因此,类似于说数字1“有值”,而实际上它是一个值。但是NULL表示非值。作为一种手动解决方法,您通常可以从MyTable WHERE coalesce(MyColumn,'x')'x'
中选择*来指定一个常量(如果它是NULL值),前提是为sentinel值x(在本例中为字符串/字符)提供适当的数据类型。这是TSQL语法,但Oracle和其他引擎具有类似的功能。事实上,我相信92规范中有
,但大多数供应商都支持=代码>和/或它包含在以后的规范(如99或03)中。@Thomas:Oracle不支持=据我所知,代码>直到~9i,这带来了大量ANSI-92语法。我相信MySQL也是类似的,从4.x开始支持。这似乎表明=
可能已作为
的替代品包含在以后的规范中。我没有掌握新的规格,所以我不能肯定。这是WHERE MyColumn!=NULL
或其中MyColumn=NULL
确定?或者换句话说,无论数据库中的MyColumn是否为空,它是否保证始终返回0行?还应该注意,因为=代码>仅计算值,执行类似于WHERE MyColumn!='somevalue“
不会返回空记录。+1。。。还不够快。现在,何时可以在索引中获得“重复”空值(您可以通过在筛选索引中添加WHERE子句(例如,在MyTable(Column)上创建唯一索引UK_MyTable,其中Column不为null
),在SQL Server索引中获得重复的空值):文档中的说明:当设置ANSI_空值
处于禁用状态时,等于(=)且不等于()比较运算符不遵循ISO标准。使用WHERE column\u name=NULL
的SELECT语句返回列\u name中具有NULL值的行。使用WHERE column\u name NULL
的SELECT语句返回列中具有非NULL值的行。此外,使用WHERE column_name XYZ_value
返回所有非XYZ_值且不为NULL的行。IMHO,最后一条语句似乎有点奇怪,因为它从结果中排除了NULL!中的重要注意事项:在SQL Server的未来版本中[比2014年更新],ANSI_NULLS将始终处于打开状态,任何显式将选项设置为关闭的应用程序都将生成错误。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。当我有时在中使用null=null
时,我总是喜欢让人感到困惑一些特别的查询。如果他们抱怨,我会把它改成null!=null
:)“null=null是false”不是这样的。NULL=NULL的计算结果为unknown而非false。@dportas是这样的,但我的意思是在条件中,它不会被计算为true。@VincentRamdhanie也不会被计算为false;事实上,在postgres中,它将被计算为NULL“在SQL中,任何您计算/计算的结果为NULL的内容都将被计算为‘NULL’——这是不正确的。您所指的结果是未知的。@Mahendralia没有提供isNull函数来检查空值,但它是“”。您应该使用IS NULL或IS NOT NULL来代替ISNULL,这是另一回事。这与@Hove在回答中描述的“无意义的”逻辑是一样的。事实是,在这种情况下,不需要额外的工具;可以很容易地假设,当我们将某个值与NULL
进行比较时,我们的意思是将某个值与“具有NULL
值”进行比较,而不是将该值与“底层NULL
具有的未确定值?但我们不知道”进行比较,这显然是我们永远无法知道的。这真的会让事情变得轻松。@Pere我不会说这完全是“无稽之谈”,而且我也不确定写为NULL
比写=NULL
要困难得多。我认为如果其中columnA=columnB
与其中columnA=NULL
具有相同的解释,而不是将后者视为特殊情况,则更为一致。请记住,NULL
不是一个值。在测试变量==null
合法的编程语言中,这是因为null
具有不同的含义;它并不代表未知的东西,而是故意重置一个值。SQL不是这样。这就是为什么我把它放在引号之间,@mango;)(还有“逻辑”)。别生我的气;我说的是ANSI的“推理”,
SET ANSI_NULLS OFF
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
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
SELECT *
FROM orders
WHERE delivered=ordered;
SELECT *
FROM orders
WHERE delivered<>ordered;
IS NULL