我是一名新手,使用AdventureWorks2012
数据库学习T-SQL。我正在使用SQL Server 2014,虽然一个也适用于2008的解决方案会很棒。我接受了以下练习:
使用Sales.SpecialOffer表编写查询。显示MinQty和MaxQty列以及SpecialOfferID和Description列之间的差异。
事情是,MaxQty
允许空值,所以我试图为输出提出一个真实世界的解决方案,不涉及在那里留下空值。但是,当我尝试使用coalesce返回'No Max'时(是的,我知道我可以在那里留下NULL,但我想看看我是否可以解决这个问题),我得到的消息是{{ 1}}值'No Max'无法转换为数据类型varchar
。我假设这是因为int
作为MaxQty - MinQty
优先?
int
错误:
Msg 245,Level 16,State 1,Line 135
将varchar值'No max'转换为数据类型int时,转换失败。
我想过只返回一个无意义的整数(0或负数),但这似乎并不完美 - 如果返回0我会模糊结果实际为零的情况等等。
思想?
答案 0 :(得分:3)
您只需要确保COALESCE
函数调用的所有参数都具有一致的数据类型。因为你无法解决事实No Max
是一个字符串,所以你必须确保通过强制转换表达式将maxqty - minqty
部分视为字符串。
select specialofferid
, description
, coalesce(cast(maxqty - minqty as varchar),'No Max') 'Qty_Difference'
from sales.specialoffer;
编辑:有关错误原因的更多详细信息
如果没有显式强制转换,COALESCE
函数尝试将No Max
字符串转换为int
的原因可以解释为以下documented rule:
结果表达式的数据类型确定是不同的。 ISNULL使用第一个参数的数据类型,COALESCE遵循CASE表达式规则,返回具有最高优先级的值的数据类型。
如果您按照文档here检查不同类型的优先级,那么您会发现int
的优先级高于varchar
。
因此,只要在COALESCE
调用中混合使用数据类型,SQL Server就会尝试将所有不匹配参数转换为具有最高优先级的数据类型,在本例中为int
。要覆盖该默认行为,需要使用显式类型转换。
答案 1 :(得分:0)
我会使用一个案例陈述,这样你就可以做你想要的东西。
select specialofferid
, description
, CASE
WHEN maxqty is null THEN 'No Max'
ELSE (maxqty - minqty) 'Qty_Difference'
END
from sales.specialoffer;