我已经看到很多人使用COALESCE函数代替ISNULL。从互联网搜索中,我发现COALESCE是ANSI标准,因此我们知道使用它的好处。但是,ISNULL似乎更易于阅读,因为它看起来更清楚自己在做什么。

我也意识到ISNULL有点棘手,因为它在不同的数据库服务器和不同的语言上有不同的作用。

在我看来,所有这些都归结为风格和标准。鉴于样式是主观的,是否有任何理由在ISNULL上使用COALESCE(反之亦然)?具体来说,是否有一个相对于另一个的性能优势?

评论

我没有在任何答案中看到提到COALESCE中的子查询被评估两次。

“ ISNULL似乎更容易阅读,因为它看起来更清楚正在做什么” –真的吗?我发现名称不符合直觉:我希望它返回一个布尔值,指示表达式解析为null还是未知。名称COALESCE只是不直观;)

#1 楼

COALESCE在内部翻译为CASE表达式,ISNULL是内部引擎函数。

COALESCE是ANSI标准函数,ISNULL是T-SQL。

性能差异可以做到当选择影响的执行计划,但在原始函数速度差产生微乎其微。

#2 楼


ISNULL是特定于Sybase / SQL Server的
COALESCE是可移植的

然后


ISNULL接受2个参数
COALESCE接受1个参数-n参数

最后,还有一点乐趣。结果数据类型和长度/精度/小数位数


ISNULL与第一个参数相同
根据数据类型优先级,COALESCE最高


这最后一个原因是为什么通常使用ISNULL的原因,因为它更容易预测(?),并且COALESCE可以添加意外的数据类型转换:这是“较慢”位来自的地方

DECLARE @len10 varchar(10); --leave it NULL
SELECT
    ISNULL(@len10, '0123456789ABCDEF'),     -- gives 0123456789
    COALESCE(@len10, '0123456789ABCDEF');   -- gives 0123456789ABCDEF


所有数据类型都是相同的,您将看不到任何实际的区别...

#3 楼

正如Mark所指出的那样,您将很难找到性能差异。我认为其他因素将更为重要。对我来说,我一直使用COALESCE,您或Mark都已经提到了其中的大多数:


COALESCE是ANSI标准。如果要移植代码,这是我不必担心的另一件事。对我个人而言,这并不重要,因为我知道在Celko的课堂世界之外这种端口实际上很少发生,但是对于某些人来说,这是一个好处。
与您所说的可读性相反,我发现它可能是很难读取ISNULL,尤其是对于来自其他语言或平台(其中ISNULL返回布尔值(SQL Server中不存在))的用户。当然,COALESCE很难拼写,但至少不会导致错误的假设。
COALESCE更加灵活,因为我可以说COALESCE(a,b,c,d)而使用ISNULL时我会d必须做很多嵌套操作才能实现相同的目的。

还应该确保您知道,如果要对两个数据类型使用不同的数据类型,将如何使用这两个函数处理数据类型优先级/ precisions等。

注意

有一个例外。在当前版本的SQL Server中,这些处理方式有所不同:

SELECT COALESCE((SELECT some_aggregate_query),0); 

SELECT ISNULL((SELECT some_aggregate_query),0); 


COALESCE变体实际上将执行some_aggregate_query两次(一次检查该值,一次在非返回时返回它) -零),而ISNULL将只执行一次子查询。我在这里谈论其他一些区别:


在SQL Server中确定COALESCE和ISNULL之间