isnull vs为null

时间:2010-06-25 13:10:04

标签: sql sql-server sql-server-2005 tsql

我注意到工作中的一些查询以及SO正在使用以下形式的限制:

isnull(name,'') <> ''

为什么人们这样做而不是更简洁

有特殊原因
name is not null

是遗产还是性能问题?

10 个答案:

答案 0 :(得分:35)

where isnull(name,'') <> ''

相当于

where name is not null and name <> '' 

反过来相当于

where name <> ''

(如果名称IS NULL表示最终表达式将评估为未知且未返回该行)

ISNULL模式的使用将导致扫描并且效率较低,如下面的测试所示。

SELECT ca.[name],
       [number],
       [type],
       [low],
       [high],
       [status]
INTO   TestTable
FROM   [master].[dbo].[spt_values]
       CROSS APPLY (SELECT [name]
                    UNION ALL
                    SELECT ''
                    UNION ALL
                    SELECT NULL) ca 


CREATE NONCLUSTERED INDEX IX_TestTable ON dbo.TestTable(name)

GO


SELECT name FROM TestTable WHERE isnull(name,'') <> ''

SELECT name FROM TestTable WHERE name is not null and name <> ''
/*Can be simplified to just WHERE name <> '' */

哪个应该为您提供所需的执行计划。

enter image description here

答案 1 :(得分:13)

is not null

仅检查字段是否为空。如果该字段包含空字符串,则该字段不再为空。

isnull(name, '') <> name

检查空字符串和空字符串。

答案 2 :(得分:2)

isnull(name,'') <> :name(name is null or name <> :name)的简写(假设:name从不包含空字符串,因此为什么这样的短序可能会很糟糕。)

性能方面,这取决于。 or条款中的where语句可能会导致极差的表现。但是,列上的功能会影响索引使用。像往常一样:个人资料。

答案 3 :(得分:1)

isnull(name,'') <> name

我可以看到他们使用这个,因为这样如果名称不匹配或为null,则返回失败的比较。这实际上意味着:name is nullname <> name

这个name is not null只检查名称是否为空。

答案 4 :(得分:1)

他们的意思不一样。

name is not null 

这将检查名称字段为空的记录

isnull(name,'') <> name  

这个将空字段的值更改为空字符串,以便可以在比较中使用它们。在SQL Server中(但我认为不在Oracle中),如果值为null并且用于比较equlaity或不等式,则不会将其视为null,因为null表示我不知道该值,因此不是实际值。因此,如果要确保在进行比较时考虑空记录,则需要ISNULL或COALESCE(这是用作ISNULL的ASCII标准术语在所有数据库中都不起作用)。

您应该关注的是

之间的差异
isnull(a.name,'') <> b.name  

a.name&lt;&gt; b.name

然后你就会明白为什么需要ISNULL来获得正确的结果。

答案 5 :(得分:1)

我显然误读了你的问题。那么让我来看看我的第一个答案,试试这个:

isnull(name,'') <> ''

的误导捷径
name is not null and name <> ''

答案 6 :(得分:1)

其他人指出了功能上的差异。至于性能问题,在Postgres我发现 - 哦,我应该提到Postgres有一个功能“coalesce”,相当于其他一些SQL方言中的“isnull” - 但是在Postgres中说

where coalesce(foobar,'')=''

明显快于

where foobar is null or foobar=''

此外,说出

可以非常快得多
 where foobar>''

where foobar!=''

大于测试可以使用索引,因此跳过所有空白,而不相等的测试必须执行完整文件读取。 (假设您在该字段上有索引,并且没有优先使用其他索引。)

答案 7 :(得分:0)

此外,如果您想使用该列的索引,请使用

name is not null and name <> '' 

答案 8 :(得分:0)

这两个查询不一样。例如,我没有中间名,这是一个已知的事实,可以存储为

MiddleName=''

但是,如果我们不知道某人的中间名,我们可以存储NULL。 因此,ISNULL(MiddleName,'')的意思是“没有已知中间名的人”。

答案 9 :(得分:0)

处理空字符串和NULL。虽然能够使用一个语句很好,但isnull是专有语法。我会用便携式标准SQL编写这个

NULLIF(name, '') IS NOT NULL