使用ISNULL与使用COALESCE检查特定的条件?
我知道可以将多个parameter passing给COALESCE
,但是如果您只想检查一个expression式以查看它是否不存在,那么您使用默认还是使用ISNULL
而不是使用ISNULL
?
两者之间是否有性能提升?
MIcrosoft Connect上报告的这个问题揭示了COALESCE
和ISNULL
之间的一些差异:
我们处理的早期部分重写
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之间决定参数时必须注意:
- COALESCE根据数据types优先级确定输出的types,与ISNULL一样,数据types不受数据types优先级的影响。
-
考虑下面的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/
NULL
和COALESCE
并不总是可以互换的。 它应该知道它们之间的差异,以便知道何时更好地使用这个差异:
上面的表格是来自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
ISNULL
和COALESCE
之间的比较。
- 支持的参数数目 – 当使用
COALESCE
时,ISNULL
为2
,VS>2
-
ISNULL
是专有的T-SQLfunction,COALESCE
是ISO / ANSI SQL标准 -
结果的数据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
失败。 -
结果的可空性也是重要的。 例如:
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
。 -
根据SQL标准,将
COALESCE
expression式转换为: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