使用ISNULL与使用COALESCE检查特定的条件?

我知道可以将多个parameter passing给COALESCE ,但是如果您只想检查一个expression式以查看它是否不存在,那么您使用默认还是使用ISNULL而不是使用ISNULL

两者之间是否有性能提升?

MIcrosoft Connect上报告的这个问题揭示了COALESCEISNULL之间的一些差异:

我们处理的早期部分重写COALESCE( expression1, expression2 )作为CASE WHEN expression1 IS NOT NULL THEN expression1 ELSE expression2 END 。 在[这个例子]中:

 COALESCE ( ( SELECT Nullable FROM Demo WHERE SomeCol = 1 ), 1 ) 

我们生成:

 SELECT CASE WHEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) IS NOT NULL THEN (SELECT Nullable FROM Demo WHERE SomeCol = 1) ELSE 1 END 

查询处理的后期不理解这两个子查询最初是相同的expression式,所以它们执行两次子查询…

一种解决方法,虽然我讨厌build议它,但是将COALESCE更改为ISNULL,因为后者不会重复子查询。

我认为不是,但是COALESCE是在SQL'92标准和更多不同的数据库支持。 如果你去便携,不要使用ISNULL。

在COALESCE中 ,可以有多个expression式,在ISNULL中只能检查一个expression式

 COALESCE ( expression [ ,...n ] ) ISNULL ( check_expression , replacement_value ) 

值得一提的是,两者之间的types处理也可以有所作为(见相关的答案(2) )。

说一个查询试图使用一个快捷方式来写空比较:

 select * from SomeTable where IsNull(SomeNullableBitField, -1) != IsNull(SomeOtherNullableBitField, -1); 

这是不同的

 select * from SomeTable where coalesce(SomeNullableBitField, -1) != coalesce(SomeOtherNullableBitField, -1); 

因为在第一种情况下,IsNull()强制types是一个位(所以-1被转换为true),而第二种情况将促进两个int。

 with input as ( select convert(bit, 1) as BitOn, convert(bit, 0) as BitOff, convert(bit, null) as BitNull ) select BitOn, BitOff, BitNull, IsNull(BitOn, -1) IsNullBitOn, -- true IsNull(BitOff, -1) IsNullBitOff, -- false IsNull(BitNull, -1) IsNullBitNull, -- true, converts the -1 to bit coalesce(BitOn, -1) CoalesceBitOn, -- 1 coalesce(BitOff, -1) CoalesceBitOff, -- 0 coalesce(BitNull, -1) CoalesceBitNull -- -1 from input; 

关于这个问题,有一个类似的评论/链接(@Martin Smith)。

我没有看到明确指出的一件大事是ISNULL的输出types与第一个expression式类似,但是使用COALESCE它返回最高优先级值的数据types。

 DECLARE @X VARCHAR(3) = NULL DECLARE @Y VARCHAR(10) = '123456789' /* The datatype returned is similar to X, or the first expression*/ SELECT ISNULL(@X, @Y) ---> Output is '123' /* The datatype returned is similar to Y, or to the value of highest precedence*/ SELECT COALESCE(@X, @Y) ---> Output is '123456789' 

在只有一个空条件的情况下, ISNULL将具有较less的开销。 不过,这个差别可能是微不足道的。

这个解释清楚地说明了合并vs isnull

SQL中的COALESCE函数返回其参数中的第一个非NULLexpression式。 COALESCE的语法如下所示:

  COALESCE ("expression 1", "expressions 2", ...) 

它与以下CASE语句相同:

 SELECT CASE ("column_name") WHEN "expression 1 is not NULL" THEN "expression 1" WHEN "expression 2 is not NULL" THEN "expression 2" ... [ELSE "NULL"] END FROM "table_name"; 

在SQL Server中,ISNULL()函数用于用另一个值replaceNULL值。

 select CountryName = ISNULL("columnname", 'INDIA') from Countries 

合并返回第一个非nullexpression式,其中asnull()用于用我们期望的值replacenull值。

COALESCE是ANSI标准的一部分,几乎可以在所有数据库中使用。

当在ISNULL v COALESCE之间决定参数时必须注意:

  1. COALESCE根据数据types优先级确定输出的types,与ISNULL一样,数据types不受数据types优先级的影响。
  2. 考虑下面的SQL语句

     DECLARE @c5 VARCHAR(5); SELECT 'COALESCE', COALESCE(@c5, 'longer name') UNION ALL SELECT 'ISNULL', ISNULL(@c5, 'longer name'); 

结果:

 COALESCE longer name ISNULL longe 

发生这种情况是因为ISNULL采用了第一个参数的数据types,而COALESCE检查所有的元素并select最合适的值(在本例中为VARCHAR(11))

有关决定COALESCE与ISNULL之间的更多详细说明,请查看: https : //www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/

NULLCOALESCE并不总是可以互换的。 它应该知道它们之间的差异,以便知道何时更好地使用这个差异:

在这里输入图像描述

上面的表格是来自Exam Ref 70-761 Querying Data with Transact-SQL Ben-Gan编写的Exam Ref 70-761 Querying Data with Transact-SQL书籍Exam Ref 70-761 Querying Data with Transact-SQL ISNULLCOALESCE之间的比较。


  1. 支持的参数数目 – 当使用COALESCE时, ISNULL2 ,VS >2
  2. ISNULL是专有的T-SQLfunction, COALESCE是ISO / ANSI SQL标准
  3. 结果的数据types很重要。 在阅读上表中的注释之后,请检查以下情况:

     DECLARE @x VARCHAR(3) = NULL ,@y VARCHAR(10) = '1234567890'; SELECT ISNULL(@x, @y) AS [ISNULL], COALESCE(@x, @y) AS [COALESCE]; 

    在这里输入图像描述

    ISNULL获取第一个参数的数据types,因为它是非NULL文字。 它是VARCHAR(3)并且是结果,第二个参数数据被剪切以匹配它。 如果使用COALESCE ,则使用最高优先级的数据types。

     DECLARE @x VARCHAR(8) = '123x5' ,@y INT = 123; SELECT ISNULL(@x, @y) AS [ISNULL]; SELECT COALESCE(@x, @y) AS [COALESCE]; 

    在这里输入图像描述

    在这里输入图像描述

    ISNULL返回第一个参数的数据types,而在COALESCE我们得到错误,因为INT优先级最高,而第一个参数值转换为INT失败。

  4. 结果的可空性也是重要的。 例如:

     DECLARE @x VARCHAR(3) = NULL ,@y VARCHAR(3) = NULL; DROP TABLE IF EXISTS [dbo].[DataSource01]; SELECT ISNULL(10, 20) AS [C1] ,ISNULL(@x, 'text') AS [C2] ,ISNULL(@x, @y) AS [C3] INTO [dbo].[DataSource01]; DROP TABLE IF EXISTS [dbo].[DataSource02]; SELECT COALESCE(10, 20) AS [C1] ,COALESCE(@x, 'text') AS [C2] ,COALESCE(@x, @y) AS [C3] INTO [dbo].[DataSource02]; 

    让我们来检查每列的Nullable属性:

    在这里输入图像描述

    在这里输入图像描述

    使用COALESCE ,只有当所有的input都是不可空的时,我们才有列的NOT NULL属性设置为Yes

  5. 根据SQL标准,将COALESCEexpression式转换为:

     CASE WHEN (<subquery>) IS NOT NULL THEN (<subquery>) ELSE 0 END 

    如果在WHEN子句中执行子查询的结果不是NULL,SQL Server将在THEN子句中执行第二次。 换句话说,在这种情况下,它执行两次。 只有当WHEN子句中的执行结果为NULL时,SQL Server才会再次执行子查询,而不是返回ELSEexpression式。 所以当使用子查询时,ISNULL函数具有性能优势。

在COALESCE中,可以使用多个expression式,例如,它将返回非空值的值

 DECLARE @Value1 INT, @Value2 INT, @Value3 INT, @Value4 INT SELECT @Value2 = 2, @Value4 = 4 SELECT COALESCE(@Value1, @Value2, @Value3, @Value4) SELECT COALESCE(@Value1, @Value4, @Value3, @Value2) 

而在ISNULL中,如果expression式为null,它将返回提供的第二个参数,当然,您可以只检查一个expression式…

所以如果要检查多个expression式并且先select其中不为空,那么使用合并否则去ISNULL