我也意识到ISNULL有点棘手,因为它在不同的数据库服务器和不同的语言上有不同的作用。
在我看来,所有这些都归结为风格和标准。鉴于样式是主观的,是否有任何理由在ISNULL上使用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之间
评论
我没有在任何答案中看到提到COALESCE中的子查询被评估两次。“ ISNULL似乎更容易阅读,因为它看起来更清楚正在做什么” –真的吗?我发现名称不符合直觉:我希望它返回一个布尔值,指示表达式解析为null还是未知。名称COALESCE只是不直观;)