TSQL中的COALESCE函数


Answers:


74

有人告诉我,COALESCE的成本比ISNULL便宜,但研究并未表明这一点。ISNULL仅采用两个参数,该字段的值评估为NULL,如果要评估为NULL,则返回所需的结果。COALESCE将采用任意数量的参数,并返回遇到的第一个非NULL值。

有关详细信息的详细说明,请 参见http://www.mssqltips.com/sqlservertip/2689/deciding-between-coalesce-and-isnull-in-sql-server/


6
当心使用ISNULL,它不是标准的,不太灵活,我读到它将始终返回第一个参数的数据类型,而不是像返回值那样返回返回值的数据类型COALESCE
sprocket12 2013年

215

我不确定您为什么认为文档含糊不清。

它只是简单地一个接一个地遍历所有参数,然后返回第一个参数NOT NULL

COALESCE(NULL, NULL, NULL, 1, 2, 3)
=> 1


COALESCE(1, 2, 3, 4, 5, NULL)
=> 1


COALESCE(NULL, NULL, NULL, 3, 2, NULL)
=> 3


COALESCE(6, 5, 4, 3, 2, NULL)
=> 6


COALESCE(NULL, NULL, NULL, NULL, NULL, NULL)
=> NULL

它几乎接受任何数量的参数,但是它们应该是相同的数据类型。 (如果它们不是相同的数据类型,则使用数据类型的优先级顺序将它们隐式转换为适当的数据类型。)

就像ISNULL()但是对于多个参数,而不仅仅是两个。

它也是ANSI-SQL,而ISNULL()不是。


4
+1为您提供有关数据类型优先级的说明。我相信这会ISNULL返回与第一个参数相同的数据类型的值
Lamak 2012年

5
您的最后一个代码示例应给出错误信息“至少COALESCE的一个参数必须为类型NULL”源:sql-server-performance.com/2007/…– maqk 2013
10:52

2
文档说了很多,同时还设法提供了几乎为零的值。好的文档提供了一个简单的示例,并且结果简单。Coalesce立即进入expressions,与CASE比较,与ISNULL比较,最后是一个没有结果的示例。然后是一个过于复杂的示例,其中包含太多细节。当我们需要的只是使用WTF 5-6行的答案时,这件事就已经做到了。
P.Brian.Mackey


18

这是我看待COALESCE的方式...希望这是有道理的...

以简单的形式…。

Coalesce(FieldName,'Empty')

因此,这转换为…如果“ FieldName”为NULL,则用单词“ EMPTY”填充字段值。

现在获取多个值...

Coalesce(FieldName1,FieldName2,Value2,Value3)

如果Fieldname1中的值为null,则用Fieldname2中的值填充,如果FieldName2为NULL,则用Value2等填充。

这段AdventureWorks2012示例数据库的测试代码可以完美地工作,并且对COALESCE的工作方式给出了很好的可视化解释:

SELECT Name, Class, Color, ProductNumber,
COALESCE(Class, Color, ProductNumber) AS FirstNotNull
FROM Production.Product


3

这是一个包含合并的简单查询-

select * from person where coalesce(addressId, ContactId) is null.

它将返回addressId和contactId均为null的人员。

合并功能

  • 需要至少两个参数。
  • 参数必须是整数类型。
  • 返回第一个非空参数。

例如

  • coalesce(null,1,2,3)将返回1。
  • coalesce(null,null)将返回null。

1

Coalesce()函数的最简单定义是:

Coalesce()函数对所有传递的参数求值,然后返回该参数的第一个实例的值(未求值为NULL)。

注意:它评估所有参数,即不跳过对返回的/ NOT NULL参数右侧的参数的评估。

句法:

Coalesce(arg1, arg2, argN...)

当心:除了计算结果为NULL的参数外,所有其他(NOT-NULL)参数必须具有相同的数据类型或具有匹配类型(可以“隐式自动转换”为兼容的数据类型),请参见示例下面:

PRINT COALESCE(NULL, ('str-'+'1'), 'x')  --returns 'str-1, works as all args (excluding NULLs) are of same VARCHAR type.
--PRINT COALESCE(NULL, 'text', '3', 3)    --ERROR: passed args are NOT matching type / can't be implicitly converted.
PRINT COALESCE(NULL, 3, 7.0/2, 1.99)      --returns 3.0, works fine as implicit conversion into FLOAT type takes place.
PRINT COALESCE(NULL, '1995-01-31', 'str') --returns '2018-11-16', works fine as implicit conversion into VARCHAR occurs.

DECLARE @dt DATE = getdate()
PRINT COALESCE(NULL, @dt, '1995-01-31')  --returns today's date, works fine as implicit conversion into DATE type occurs.

--DATE comes before VARCHAR (works):
PRINT COALESCE(NULL, @dt, 'str')      --returns '2018-11-16', works fine as implicit conversion of Date into VARCHAR occurs.

--VARCHAR comes before DATE (does NOT work):
PRINT COALESCE(NULL, 'str', @dt)      --ERROR: passed args are NOT matching type, can't auto-cast 'str' into Date type.

高温超导


0
declare @store table (store_id varchar(300))
insert into @store 
values ('aa'),('bb'),('cc')
declare @str varchar (4000)
select @str = concat(@str+',',store_id) from @store
select @str

1
我发现这要简单得多。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.