从合并的 int 计算返回 varchar 值

Returning a varchar value from a coalesced int calculation

我是一个新手,正在使用 AdventureWorks2012 数据库学习 T-SQL。我使用的是 SQL Server 2014,但也适用于 2008 的解决方案会很棒。我得到了以下练习:

Write a query using the Sales.SpecialOffer table. Display the difference between the MinQty and MaxQty columns along with the SpecialOfferID and Description columns.

事实是,MaxQty 允许空值,所以我试图为不涉及在其中留下空值的输出提出一个真实世界的解决方案。但是,当我尝试使用 coalesce to return 'No Max' (是的,我知道我可以在那里留下 NULL 但我想看看我是否能解决这个问题),我得到了varchar 值 'No Max' 无法转换为数据类型 int 的消息。我假设这是因为 MaxQty - MinQty 作为 int 优先?

select 
    specialofferid
    , description
    , coalesce((maxqty - minqty),'No Max') 'Qty_Difference'
from 
    sales.specialoffer;

错误:

Msg 245, Level 16, State 1, Line 135
Conversion failed when converting the varchar value 'No max' to data type int.

我只想 return 一个无意义的整数(0 或负数),但这似乎并不完美 - 如果 return 0 我在掩盖结果实际上为零的情况等

想法?

我会使用 case 语句,这样您就可以做您想做的事情。

select specialofferid
, description
, CASE 
     WHEN  maxqty is null THEN 'No Max'
     ELSE (maxqty - minqty) 'Qty_Difference'
  END
from sales.specialoffer;

您只需要确保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 解释:

Data type determination of the resulting expression is different. ISNULL uses the data type of the first parameter, COALESCE follows the CASE expression rules and returns the data type of value with the highest precedence.

如果您检查不同类型的优先级,如 here 所述,那么您会发现 int 的优先级高于 varchar

因此,一旦您在对 COALESCE 的调用中混合了数据类型,SQL 服务器将尝试将所有不匹配的参数转换为具有最高优先级的数据类型,在这种情况下int。要覆盖该默认行为,需要显式类型转换。