3

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

使用 Sales.SpecialOffer 表编写查询。显示 MinQty 和 MaxQty 列以及 SpecialOfferID 和 Description 列之间的差异。

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

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

错误:

消息 245,级别 16,状态 1,行 135
将 varchar 值“无最大值”转换为数据类型 int 时转换失败。

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

想法?

4

2 回答 2

4

您只需要确保COALESCE函数调用的所有参数都具有一致的数据类型。因为您无法绕过No Max字符串是字符串的事实,所以您必须通过强制转换表达式来确保该maxqty - minqty部分也被视为字符串。

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

编辑:有关错误原因的更多详细信息

如果没有显式强制COALESCE转换,函数尝试将No Max字符串转换为 an的原因int可以通过以下记录的规则来解释:

结果表达式的数据类型确定是不同的。ISNULL 使用第一个参数的数据类型,COALESCE 遵循 CASE 表达式规则,返回优先级最高的 value 的数据类型。

而且,如果您检查不同类型的优先级,如此处所述那么您将看到它int的优先级高于varchar.

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

于 2015-07-16T18:17:32.523 回答
0

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

select specialofferid
, description
, CASE 
     WHEN  maxqty is null THEN 'No Max'
     ELSE (maxqty - minqty) 'Qty_Difference'
  END
from sales.specialoffer;
于 2015-07-16T18:04:45.243 回答