使用ISNULL vs使用COALESCE检查特定条件?

时间:2011-09-13 21:40:22

标签: sql tsql coalesce isnull

我知道可以将多个参数传递给COALESCE,但是在您想要的时候 只检查一个表达式以查看它是否不存在,您是使用默认值还是使用ISNULL更好的做法?

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

9 个答案:

答案 0 :(得分:55)

This problem reported on 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
     

查询处理的后续阶段不理解这两个子查询最初是同一个表达式,因此它们执行子查询两次......

     

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

答案 1 :(得分:24)

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

答案 2 :(得分:11)

COALESCE中,您可以有多个表达式,而在ISNULL中,您只能检查一个表达式

COALESCE ( expression [ ,...n ] ) 

ISNULL ( check_expression , replacement_value )

答案 3 :(得分:6)

值得一提的是,两者之间的类型处理也会产生影响(参见this related answer item (2))。

假设查询尝试使用快捷方式编写空比较:

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

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

因为在第一种情况下,IsNull()强制类型为一位(因此-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)。

答案 4 :(得分:5)

我没有明确指出的一个主要问题是ISNULL的输出类型与第一个表达式类似,但是COALESCE它返回最高优先级值的数据类型。

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'

答案 5 :(得分:2)

如果只有一个空条件,ISNULL将减少开销。但差异可能微乎其微。

答案 6 :(得分:2)

这个解释清楚地表明了coalesce vs isnull

SQL中的COALESCE函数返回其参数中的第一个非NULL表达式。 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()函数用于将NULL值替换为另一个值。

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

Coalesce返回第一个非null表达式,其中asnull()用于将null值替换为所需的值。

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

在判断ISNULL v COALESCE之间时,必须注意参数:

  1. COALESCE根据数据类型优先级确定输出的类型,而对于ISNULL,数据类型不受数据类型优先级的影响。
  2. 请考虑以下sql语句

    DECLARE @c5 VARCHAR(5);
    SELECT 'COALESCE', COALESCE(@c5, 'longer name')
    UNION ALL
    SELECT 'ISNULL',   ISNULL(@c5,   'longer name');
    
  3. 结果:

    COALESCE longer name
    ISNULL   longe
    

    这是因为ISNULL采用第一个参数的数据类型,而COALESCE检查所有元素并选择最合适(在本例中为VARCHAR(11))

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

答案 7 :(得分:1)

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

enter image description here

上表是Itzik Ben-Gan撰写的ISNULL书中的COALESCEExam Ref 70-761 Querying Data with Transact-SQL之间的比较。

  1. 支持的参数数量 - 使用2ISNULL>2的{​​{1}}
  2. COALESCE是专有的T-SQL功能,ISNULL是ISO / ANSI SQL标准
  3. 结果的数据类型很重要。阅读上表中的注释后,请检查以下情况:

    COALESCE

    enter image description here

    DECLARE @x VARCHAR(3) = NULL ,@y VARCHAR(10) = '1234567890'; SELECT ISNULL(@x, @y) AS [ISNULL], COALESCE(@x, @y) AS [COALESCE]; 获取第一个参数的数据类型,因为它不是 ISNULL字面意思。它是NULL并且是结果,第二个参数数据 切割以匹配它。使用VARCHAR(3)数据类型,如果最高优先级是 使用

    COALESCE

    enter image description here

    enter image description here

    DECLARE @x VARCHAR(8) = '123x5' ,@y INT = 123; SELECT ISNULL(@x, @y) AS [ISNULL]; SELECT COALESCE(@x, @y) AS [COALESCE]; 正在返回第一个参数的数据类型 ISNULL我们收到错误,因为COALESCE具有最高优先权和。{1}} 将第一个参数值转换为INT失败。

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

    INT

    让我们检查每列的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]; 属性:

    enter image description here

    enter image description here

    使用Nullable我们将COALESCE列的属性设置为NOT NULL 当所有输入都不可为空时。

  5. 根据SQL标准,Yes表达式被翻译为:

    COALESCE
      

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

答案 8 :(得分:-2)

在COALESCE中,可以使用多个表达式,它将返回非空的值并首先出现...例如

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中,如果表达式为null,它将返回提供的第二个参数,当然,您只能检查一个表达式...

因此,如果要检查多个表达式并在它们中首先选择not null,那么使用coalesce,否则转到ISNULL