从合并的int计算返回varchar值

时间:2015-07-16 17:56:40

标签: sql sql-server-2008 sql-server-2014-express

我是一名新手,使用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我会模糊结果实际为零的情况等等。

思想?

2 个答案:

答案 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;